Load packages

library(tidyverse) # tidy style coding
library(brms) # Bayesian models
library(bayesplot) # pretty bayes visuals
library(tidybayes) # Bayesian aesthetics
library(loo) # to use information criteria in brms models
library(MetBrewer) # colours
library(rcartocolor) # more colours
library(pander) # tables
library(kableExtra) # tables
library(patchwork) # putting plots together
library(DT) # for search- and saveable tables
library(ggdist) # for ribbon plot
library(png) # to load images
library(grid) # to plot images

Supplementary methods

\(~\)

Table S1. Recipe for food medium used in our experiment. The provided quantities make ~ 1 litre of food.

tibble("Ingredients" = c("Soy flour", "Cornmeal", "Yeast", "Dextrose", "Agar", "Water", "Tegosept", "Acid mix (4 mL orthophosphoric acid, 41 mL propionic acid, 55 mL water to make 100 mL)"),
       "Quantity" = c("20 g", "73 g", "35 g", "75 g", "6 g", "1000 mL", "17 mL", "14 mL")) %>% 
  pander(split.cell = 40, split.table = Inf)
Ingredients Quantity
Soy flour 20 g
Cornmeal 73 g
Yeast 35 g
Dextrose 75 g
Agar 6 g
Water 1000 mL
Tegosept 17 mL
Acid mix (4 mL orthophosphoric acid, 41 mL propionic acid, 55 mL water to make 100 mL) 14 mL

\(~\)

img <- readPNG("Figure_S1.png")
 
grid.raster(img)

Figure S1. Crossing scheme used to integrate the GFP constructs and apXA marked translocated second and third chromosome balancers into the LHM genetic background. We replicated the crosses 12 times to supply the flies used in generation zero of experimental evolution; 6 times using the Ubi GFP construct and 6 times with the 3xP construct. G = generation.

\(~\)

Analysis

\(~\)

Mortality analysis

\(~\)

We conducted single-pair full-sibling crosses to erode heterozygosity across the genome, thereby exposing mutation load. Our proxies for mutation load - extinction rate and productivity decline - may also have been affected by differences in the intensity of interlocus sexual conflict between subpopulations carrying autosomes with different selection response histories. We specifically designed our experiment to minimise this effect, by enforcing monogamy between all breeding individuals across the extinction assay. However, we cannot discount males carrying male-limited autosomes and/ or control autosomes being more harmful to females than males carrying autosomes with a female-limited selection response history. This might occur because male harm is a by-product of male-male competition, which cannot respond to selection in the female-limited treatments. Furthermore, traits genetically correlated with harm such as activity levels or metabolic rate may be selected in the opposite direction among females, as these traits are highly sexually dimorphic. This may drive the evolution of reduced harm during female-limited evolution.

We observe 135 female (6.2%) and 21 (1%) male mortalities across the 2184 Drosophila vials used during the 20 generations of the experiment (we do not include the 9 final generations observed in Block 1 in this analysis). Male mortality did not occur often enough to provide the power required for formal analysis. We instead focus on modelling female mortality and test whether this is affected by selection response history.

We test this hypothesis to assess whether it is required to censor subpopulations where the breeding female died in the generation of extinction.

\(~\)

Load in the data

mortality_data <- 
  read_csv("Data/Mortality_data.csv") %>% 
  rowid_to_column("subpopulation") %>% 
  pivot_longer(cols = 8:27, names_to = "Generation", values_to = "Female_mortality") %>% 
  mutate(
    Generation = as.integer(str_remove(Generation, "Gen_")),
    Week = case_when(
    Block == 1 ~ Generation,
    Block == 2 ~ as.integer(Generation + 9)),
    Week = as.factor(Week),
    across(1:7, as.factor),
    Male_mortality = Female_mortality,
    Female_mortality = if_else(Female_mortality == "FEMALE" | Female_mortality == "BOTH", 1, 0),
    Male_mortality = if_else(Male_mortality == "MALE" | Male_mortality == "BOTH", 1, 0)) %>% 
  rename(Evolution_treatment = Treatment)


# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'mortality_data')),
      pageLength = 8500
    )
  )
}

my_data_table(mortality_data %>% 
                select(Mother_strain, Father_strain, Cross, subpopulation, Block, Week, Generation, Evolution_treatment, Female_mortality, Male_mortality))

\(~\)

Column explanations

Mother strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same Evolution_treatment. This column shows the strain that the founding female of the subpopulation was derived from.

Father strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same evolution treatment. This column shows the strain that the founding male of the subpopulation was derived from.

Cross: an identifying ID for each of the 36 combinations of Mother strain and Father strain.

subpopulation: lines of flies founded by single inseminated females in generation zero. We generated the next generation of each subpopulation by crossing a single full-sibling dyad.

Block: the experiment was run in 2 distinct blocks, using flies separated by 9 generations.

Week: the week that the generation of each block was conducted in. Laboratory conditions may have differed slightly between weeks. For example, a new batch of food was cooked for each week. Note that blocks overlap between weeks 9-20.

Generation: the generation of the extinction assay, ranging from 1 to 20.

Evolution_treatment: the strains had been exposed to one of three evolutionary conditions for 20 generations: a female-limited response to selection, a male-limited response and a control condition where an evolutionary response occurred in both sexes.

Female_mortality: a 0 indicates the female survived until she was removed from the 3-day breeding vial. A 1 indicates she died during this period. Females were 1-4 days old when they entered the breeding vial.

Male_mortality: see Female_mortality, except this column documents male mortality in the breeding vials.

\(~\)

Modelling approach

\(~\)

We fit a binomial model with Female_mortality as the response, Evolution_treatment as a fixed effect and Week, subpopulation and Cross as random effects.

Priors

We fit moderately informative priors, with the aim to regularise our posterior estimates and improve model fitting by ruling out non-sensical values.

Note that each of these priors is expressed on the logit scale, due to the binomial logit link.

\(\alpha\) (the intercepts) ~ Normal(\(\mu\) = -2, \(\sigma\) = 2)

\(\beta\) (the fixed effects) ~ Normal(\(\mu\) = 0, \(\sigma\) = 2)

\(\sigma\) ~ Exponential(rate = 1)

female_mortality_model <- 
  brm(Female_mortality ~ 1 + Evolution_treatment + (1|Week) + (1|Cross) + (1|subpopulation),
      data = mortality_data %>% filter(Female_mortality != "NA"),
      family = bernoulli,
      prior = c(prior(normal(-2, 2), class = Intercept),
                prior(normal(0, 2), class = b),
                prior(exponential(1), class = sd)),
      iter = 8000, warmup = 4000, chains = 4, cores = 4, seed = 1,
      control = list(adapt_delta = 0.98),
      file = "Fits/female_mortality_model")

Extract model predictions and plot

mortality_predictions <-
  female_mortality_model %>% 
  as_draws_df() %>% 
  mutate(Control = inv_logit_scaled(b_Intercept)*100,
         `Female-limited` = inv_logit_scaled(b_Intercept + b_Evolution_treatmentFemale)*100,
         `Male-limited` = inv_logit_scaled(b_Intercept + b_Evolution_treatmentMale)*100) %>% 
  select(Control, `Female-limited`, `Male-limited`)
    
# put in easy to plot format

mortality_predictions_long <-
  mortality_predictions %>% 
  pivot_longer(cols = everything(), names_to = "Evolution_treatment", values_to = "Mortality")

# calculate the differences between each treatment

mortality_diff <-
  mortality_predictions %>% 
  mutate(`Control - Male-limited` = Control - `Male-limited`,
         `Male-limited - Female-limited` = `Male-limited` - `Female-limited`,
         `Control - Female-limited` = Control - `Female-limited`) %>% 
  pivot_longer(cols = 4:6, names_to = "Difference_contrast", values_to = "Difference") %>% 
  select(contains("Diff"))

Build Figure S2

mortality_plot <-
  mortality_predictions_long %>% 
  ggplot(aes(x = Mortality, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "median_qi", point_fill = "white", 
               shape = 21, point_size = 4, stroke = 1.5) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x= "Female mortality (%)", y = "Inheritance treatment") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

mortality_diff_plot <- 
  mortality_diff %>% 
  ggplot(aes(x = Difference, y = fct_relevel(Difference_contrast, "Control - Female-limited", "Male-limited - Female-limited", "Control - Male-limited"))) +
  stat_halfeye(aes(fill = Difference_contrast), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5) + 
  scale_fill_manual(values = c(carto_pal(7, "Peach")[2], carto_pal(7, "Purp")[1], carto_pal(7, "TealGrn")[1])) +
  geom_vline(xintercept = 0, linetype = 2, colour = "black", linewidth = 1) +
  labs(x = "Diff. in mortality (% points)", y = "Treatment contrast") +
  scale_x_continuous(breaks=seq(-2, 6, 2), limits = c(-3, 7)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(),
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

  mortality_plot / mortality_diff_plot +
  plot_annotation(tag_levels = 'a')

Figure S2. Female mortality is less frequent in subpopulations with female-limited selection response histories, suggesting that male harm may be less intense in these subpopulations. Panel a shows the posterior distribution of the mean percentage of female mortality events across the total number of vials that housed subpopulations throughout the extinction assay, split by selection response history. Panel b shows the posterior distribution of the difference between each treatment. The points show the estimated median, with associated 66 and 95% credible intervals.

\(~\)

To avoid this confounding our measure of mutation load, we can censor extinction events that co-occur with female mortality.

\(~\)

Extinction analysis

Load in the extinction data

\(~\)

extinction_data <- 
  read_csv("Data/Extinction_data.csv") 

# Block 1 runs for 29 generations, while Block 2 only runs for 20. To calculate the censoring variable, we need to split these by Block, mutate the data, then rebind them 

Block_1 <-
  extinction_data %>% 
  filter(Block == "1") %>% 
  # here we create a censoring column. If the family a) escaped or was killed by something unrelated to the experiment or b) survived the 20 generations of the experiment, then we code a value of 1. If the family went extinct, we code a value of 0. This allows us to right censor the data, thereby preserving the information it provides on extinction.
  mutate(across(Gen_1:Gen_29, ~replace_na(.x, "Escape")),
         Censored_alive = if_else(Gen_29 == "YES", 1, 0),
         Censored_escape = if_else(Gen_29 == "Escape", 1, 0),
         Censored = Censored_alive + Censored_escape,
         across(Gen_1:Gen_29, ~if_else(.x == "YES", 1, 0)))
        

Block_2 <-
  extinction_data %>% 
  filter(Block == "2") %>% 
  # here we create a censoring column. If the family a) escaped or was killed by something unrelated to the experiment or b) survived the 20 generations of the experiment, then we code a value of 1. If the family went extinct, we code a value of 0. This allows us to right censor the data, thereby preserving the information it provides on extinction.
  mutate(across(Gen_1:Gen_20, ~replace_na(.x, "Escape")),
         across(Gen_21:Gen_29, ~replace_na(.x, "Not measured")),
         Censored_alive = if_else(Gen_20 == "YES", 1, 0),
         Censored_escape = if_else(Gen_20 == "Escape", 1, 0),
         Censored = Censored_alive + Censored_escape,
         across(Gen_1:Gen_29, ~if_else(.x == "YES", 1, 0)))

# combine the Blocked data back into a single tibble

extinction_data_wrangled <-
  rbind(Block_1, Block_2) %>%
  mutate(across(1:7, as.factor), 
         Gens_to_extinct = Gen_1 + Gen_2 + Gen_3 + Gen_4 + 
           Gen_5 + Gen_6 + Gen_7 + Gen_8 + Gen_9 + Gen_10 + 
           Gen_11 + Gen_12 + Gen_13 + Gen_14 + Gen_15 + Gen_16 + 
           Gen_17 + Gen_18 + Gen_19 + Gen_20 + Gen_21 + Gen_22 + 
           Gen_23 + Gen_24 + Gen_25 + Gen_26 + Gen_27 + Gen_28 + Gen_29 + 1) %>% 
  rename(Evolution_treatment = Treatment, subpopulation  = ID) %>% 
  select(Mother_strain, Father_strain, Cross, subpopulation, Block, 
         Evolution_treatment, Gens_to_extinct, Gen_1:Gen_29, Censored_alive, 
         Censored_escape, Censored)

# Find the extinctions that co-occur with female mortality

extinction_mortality <-
  left_join(
    extinction_data_wrangled %>% 
      pivot_longer(cols = 8:36, names_to = "Generation", values_to = "Extant") %>% 
      mutate(Generation = as.integer(str_remove(Generation, "Gen_"))),
    
    mortality_data
  ) %>% 
  filter(Extant == 0 & Female_mortality == 1) %>% 
  mutate(Censored_mortality = 1) %>% 
  select(subpopulation, Censored_mortality)

extinction_data_wrangled <- left_join(extinction_data_wrangled, extinction_mortality) %>% 
  mutate(Censored_mortality = if_else(is.na(Censored_mortality), 0, 1),
         Censored_2 = Censored + Censored_mortality)

# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'extinction_data')),
      pageLength = 500
    )
  )
}

my_data_table(extinction_data_wrangled)

Column explanations

Mother strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same Evolution_treatment. This column shows the strain that the founding female of the subpopulation was derived from.

Father strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same evolution treatment. This column shows the strain that the founding male of the subpopulation was derived from.

Cross: an identifying ID for each of the 36 combinations of Mother strain and Father strain.

subpopulation: lines of flies founded by single inseminated females in generation zero. We generated the next generation of each subpopulation by crossing a single full-sibling dyad.

Block: the experiment was run in 2 distinct blocks, using flies separated by 9 generations. Block 1 ran for 29 generations, whereas Block 2 ran for 20 generations.

Evolution_treatment: the strains had been exposed to one of three evolutionary conditions for 20-29 generations: a female-limited response to selection, a male-limited response and a control condition where an evolutionary response occurred in both sexes.

Gens_to_extinction: the number of generations the subpopulation survived until it went extinct.

Gen_1:29: a 1 indicates the subpopulation was extant for the generation in question, while a 0 indicates extinction. Note that we continued propagating surviving subpopulations from Block 1 until generation 29, which coincided with generation 20 for subpopulations belonging to the second Block.

Censored: if the subpopulation 1) ended because flies escaped or were killed by something unrelated to the experiment, 2) went extinct because of breeding female mortality or 3) was extant after the final generation of the experiment, then we coded a value of 1. If the subpopulation went extinct, we coded a value of 0. This allows us to right censor the data as per the brms syntax, thereby preserving the information these censored cases provide on extinction.

\(~\)

Modelling approach

\(~\)

We fit a weibull survival model to estimate , the extinction rate of the subpopulations used in our experiment. The weibull model is an extension of an exponential decay model, and includes an additional shape parameter, which allows to vary across generations of inbreeding.

We right censor subpopulations that 1) ended because flies escaped or were killed by something unrelated to the experiment, 2) went extinct because of breeding female mortality or 3) were extant after the final generation of the experiment

Response variable

Gens_to_extinct is our response - a continuous variable that runs from 1 to 30 generations. Note that we measured extinction up until generation 29 in Block 1 and generation 20 in Block 2. A value of 30 indicates that the subpopulation was extant at the end of the experiment in Block 1, while a value of 21 indicates this in Block 2. We also include right censoring, to account for subpopulations extant at the end of the experiment, or that were removed from the experiment by a handling error. Censoring enables the inclusion of this ‘incomplete’ data in the model.

Fixed effects

Evolution_treatment: we include this to test for a causal effect of sex-limited experimental evolution on mutation load.

Block: extinction rate might differ between the blocks we split our experiment up into e.g. because of microvariation in the lab brought about because of a change of season, slight inconsistencies in Drosophila food consistency etc.

Varying/Random effects

Cross: we initiated each subpopulation by crossing two strains belonging to the same evolution treatment. There were 12 levels of cross nested within evolution treatment, for a total of 36 crosses. We kept subpopulations from the same Cross and Block in the same column of the Drosophila vial trays, so incuding this variable also controls for micro-environmental variation caused by within-tray position. We used this random effect in our first model.

Mother_strain and Father_strain: Used as an alternative to Cross in our second model. In this case, we fit a multi-membership model, where each subpopulation simultaneously belongs to two levels of the Cross random effect. That is, each subpopulation was founded my a mother from \(strain_i\) and a father from \(strain_j\) and they therefore always belong to two levels of strain.

Multi-membership vs single-membership

While the multi-membership approach may initially seem the more powerful of the two random effect structures, we favour the single-membership approach for several reasons. First, our primary aim is to estimate the overall causal effect of evolution treatment on generations to extinction, rather than that of each strain (nested within evolution treatment). Given that we balanced our crossing design so that each strain is equally represented in the experiment, estimation for each strain is not integral. Second, Cross captures nuisance environmental variation that Strain does not. We distributed subpopulations throughout three Drosophila vial trays by placing subpopulations from the same cross in the same column. Across the columns we split subpopulations up by evolution treatment, such that column one contained subpopulations from the female-limited treatment, column two contained subpopulations from the male-limited treatment and column three contained subpopulations from the control treatment. We repeated this pattern until all 36 crosses filled a column. As a strain is used in multiple crosses, it is widely distirbuted throughout the trays and therefore does not capture a location effect like cross does. We are of the opinion that controlling for this environmental variation is of greater importance than strain level differences in mutation load, which both cross and evolution treatment also contain information for.

Finally, we fit both models and use leave one out (LOO) cross validation to formally assess which model has better expected predictive accuracy, both in and out of sample.

Priors

We fit moderately informative priors, with the aim to regularise our posterior estimates and improve model fitting by ruling out non-sensical values.

Note that each of these priors is expressed on the log scale, due to the weibull log link.

\(\alpha\) (the intercepts) ~ Gamma(shape = 5, rate = 3)

This intercept prior predicts an appropriate starting point for per generation extinction rate on the log scale.

\(\beta\) (the fixed effects) ~ Normal(\(\mu\) = 0, \(\sigma\) = 1)

\(\sigma\) ~ Exponential(rate = 1)

\(k\) (The weibull shape parameter) ~ Normal(\(\mu\) = 0, \(\sigma\) = 0.5)

Fit the models

extinction_model_sm <-
  brm(data = extinction_data_wrangled,
      family = weibull,
      bf(Gens_to_extinct | cens(Censored_2) ~ 1 + Evolution_treatment + Block + (1|Cross),
         shape ~ 1 + Evolution_treatment + Block),
      # this intercept prior predicts an appropriate starting point for per gen extinction rate on the log scale
      prior = c(prior(gamma(5, 3), class = Intercept, lb = 0),  
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd),
                prior(normal(0, 0.5), class = b, dpar = shape)), 
      iter = 8000, warmup = 4000, chains = 4, cores = 4,
      seed = 1, control = list(adapt_delta = .9, max_treedepth = 10),
       file = "Fits/extinction_model")

extinction_model_sm <- add_criterion(extinction_model_sm, criterion = "loo")

# the model does not converge when we try and fit a treatment * block interaction

extinction_model_mm <-
  brm(data = extinction_data_wrangled,
      family = weibull,
      bf(Gens_to_extinct | cens(Censored_2) ~ 1 + Evolution_treatment + Block + (1|mm(Mother_strain, Father_strain)),
      shape ~ 1 + Evolution_treatment + Block),
      # this intercept prior predicts an appropriate starting point for per gen extinction rate on the log scale
      prior = c(prior(gamma(5, 3), class = Intercept, lb = 0), 
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd),
                prior(normal(0, 0.5), class = b, dpar = shape)), 
      iter = 8000, warmup = 4000, chains = 4, cores = 4,
      seed = 2, control = list(adapt_delta = 0.98, max_treedepth = 15),
      file = "Fits/extinction_model_mm")

extinction_model_mm <- add_criterion(extinction_model_mm, criterion = "loo")

\(~\)

Model diagnostics

\(~\)

Compare models using LOO, a bayesian information criteria

loo_compare(extinction_model_sm, extinction_model_mm)  %>% 
  kable(digits = 3) %>% 
  kable_styling()
elpd_diff se_diff elpd_loo se_elpd_loo p_loo se_p_loo looic se_looic
extinction_model_sm 0.000 0.000 -1042.910 20.209 23.694 2.970 2085.820 40.418
extinction_model_mm -0.668 2.593 -1043.578 20.238 15.072 2.273 2087.155 40.475

The single-membership model performs slightly better. We present results from this model.

Lets see how the model recapitulates the data

pp_check(extinction_model_sm, type = "hist", ndraws = 11, binwidth = 1) +
  theme_minimal() +
  theme(panel.background = element_blank())

\(~\)

Interpreting model output

\(~\)

We can initially ignore the shape parameter and find the mean rate of extinction, averaged across all generations, using the equation

\(\lambda= \frac{1}{e^\mu}\)

First find distributions of \(\mu\) for each of the three treatments.

inverse_rate_weibull <-
  extinction_model_sm %>% 
  as_draws_df() %>% 
  transmute(`Control B1` = b_Intercept, 
         `Female_limited B1` = b_Intercept + b_Evolution_treatmentFemale,
         `Male_limited B1` = b_Intercept + b_Evolution_treatmentMale,
         `Control B2` = b_Intercept + b_Block2, 
         `Female_limited B2` = b_Intercept + b_Evolution_treatmentFemale + b_Block2,
         `Male_limited B2` = b_Intercept + b_Evolution_treatmentMale + b_Block2)

Now lets plug these distributions into the equation to find mean estimates of \(\lambda\).

  inverse_rate_weibull %>% 
  mutate(across(1:6, ~1 / exp(.x))) %>% 
  mutate(across(everything(), ~mean(.x))) %>% 
  distinct()
## # A tibble: 1 × 6
##   `Control B1` `Female_limited B1` `Male_limited B1` Control B…¹ Femal…² Male_…³
##          <dbl>               <dbl>             <dbl>       <dbl>   <dbl>   <dbl>
## 1        0.142               0.130             0.111       0.120   0.110  0.0941
## # … with abbreviated variable names ¹​`Control B2`, ²​`Female_limited B2`,
## #   ³​`Male_limited B2`

This is the rate of extinction per generation, averaged across all generations. However, the weibull family allows a dynamic rate rather the the constant rate that the exponential constrains it to.

Following the vignette("brms_families"), the weibull survival function can be found using the following transformation:

\(\lambda= \frac{e^\mu}{\gamma(1 + \frac{1}{k})}\)

where \(k\) is the shape parameter estimated in brms

Then we can find survival at generation \(t\) using

\(S = e^{-(\frac{t}{\lambda})^k}\)

We plug in a vector with 16000 draws from the posterior distribution for 1) \(\mu\) of each inheritance treatment and 2) \(k\) the shape parameter to find distributions of the proportion of surviving subpopulations at each generation.

# Find lambda for the three treatments. 

lambda_weibull <-
  extinction_model_sm %>% 
  as_draws_df() %>% 
  transmute(`Control B1` = b_Intercept, 
            `Female_limited B1` = b_Intercept + b_Evolution_treatmentFemale,
            `Male_limited B1` = b_Intercept + b_Evolution_treatmentMale,
            `Control B2` = b_Intercept + b_Block2, 
            `Female_limited B2` = b_Intercept + b_Evolution_treatmentFemale + b_Block2,
            `Male_limited B2` = b_Intercept + b_Evolution_treatmentMale + b_Block2,
            shape_control_B1 = exp(b_shape_Intercept),
            shape_female_B1 = exp(b_shape_Intercept + b_shape_Evolution_treatmentFemale),
            shape_male_B1 = exp(b_shape_Intercept + b_shape_Evolution_treatmentMale),
            shape_control_B2 = exp(b_shape_Intercept + b_shape_Block2),
            shape_female_B2 = exp(b_shape_Intercept + b_shape_Evolution_treatmentFemale + b_shape_Block2),
            shape_male_B2 = exp(b_shape_Intercept + b_shape_Evolution_treatmentMale + b_shape_Block2)) %>% 
  mutate(Control_lambda_B1 = exp(`Control B1`) / gamma(1 + 1/shape_control_B1),
         Female_lambda_B1 = exp(`Female_limited B1`) / gamma(1 + 1/shape_female_B1),
         Male_lambda_B1 = exp(`Male_limited B1`) / gamma(1 + 1/shape_male_B1),
         Control_lambda_B2 = exp(`Control B2`) / gamma(1 + 1/shape_control_B2),
         Female_lambda_B2 = exp(`Female_limited B2`) / gamma(1 + 1/shape_female_B2),
         Male_lambda_B2 = exp(`Male_limited B2`) / gamma(1 + 1/shape_male_B2)) %>% 
  select(contains(c("lambda", "shape")))

# Now find survival proportion at generations 1-29

Weibull_survival_curve <- 
  lambda_weibull %>% 
  mutate(#Block 1
    Control_0_B1  = exp(-(0/Control_lambda_B1)^shape_control_B1),  
    Control_1_B1  = exp(-(1/Control_lambda_B1)^shape_control_B1),
    Control_2_B1  = exp(-(2/Control_lambda_B1)^shape_control_B1),
    Control_3_B1  = exp(-(3/Control_lambda_B1)^shape_control_B1),
    Control_4_B1  = exp(-(4/Control_lambda_B1)^shape_control_B1),
    Control_5_B1  = exp(-(5/Control_lambda_B1)^shape_control_B1),
    Control_6_B1  = exp(-(6/Control_lambda_B1)^shape_control_B1),
    Control_7_B1  = exp(-(7/Control_lambda_B1)^shape_control_B1),
    Control_8_B1 = exp(-(8/Control_lambda_B1)^shape_control_B1),
    Control_9_B1 = exp(-(9/Control_lambda_B1)^shape_control_B1),
    Control_10_B1 = exp(-(10/Control_lambda_B1)^shape_control_B1),
    Control_11_B1 = exp(-(11/Control_lambda_B1)^shape_control_B1),
    Control_12_B1 = exp(-(12/Control_lambda_B1)^shape_control_B1),
    Control_13_B1 = exp(-(13/Control_lambda_B1)^shape_control_B1),
    Control_14_B1 = exp(-(14/Control_lambda_B1)^shape_control_B1),
    Control_15_B1 = exp(-(15/Control_lambda_B1)^shape_control_B1),
    Control_16_B1 = exp(-(16/Control_lambda_B1)^shape_control_B1),
    Control_17_B1 = exp(-(17/Control_lambda_B1)^shape_control_B1),
    Control_18_B1 = exp(-(18/Control_lambda_B1)^shape_control_B1),
    Control_19_B1 = exp(-(19/Control_lambda_B1)^shape_control_B1),
    Control_20_B1 = exp(-(20/Control_lambda_B1)^shape_control_B1),
    Control_21_B1 = exp(-(21/Control_lambda_B1)^shape_control_B1),
    Control_22_B1 = exp(-(22/Control_lambda_B1)^shape_control_B1),
    Control_23_B1 = exp(-(23/Control_lambda_B1)^shape_control_B1),
    Control_24_B1 = exp(-(24/Control_lambda_B1)^shape_control_B1),
    Control_25_B1 = exp(-(25/Control_lambda_B1)^shape_control_B1),
    Control_26_B1 = exp(-(26/Control_lambda_B1)^shape_control_B1),
    Control_27_B1 = exp(-(27/Control_lambda_B1)^shape_control_B1),
    Control_28_B1 = exp(-(28/Control_lambda_B1)^shape_control_B1),
    Control_29_B1 = exp(-(29/Control_lambda_B1)^shape_control_B1),
    Female_0_B1  = exp(-(0/Female_lambda_B1)^shape_female_B1),
    Female_1_B1  = exp(-(1/Female_lambda_B1)^shape_female_B1),
    Female_2_B1  = exp(-(2/Female_lambda_B1)^shape_female_B1),
    Female_3_B1  = exp(-(3/Female_lambda_B1)^shape_female_B1),
    Female_4_B1  = exp(-(4/Female_lambda_B1)^shape_female_B1),
    Female_5_B1  = exp(-(5/Female_lambda_B1)^shape_female_B1),
    Female_6_B1  = exp(-(6/Female_lambda_B1)^shape_female_B1),
    Female_7_B1  = exp(-(7/Female_lambda_B1)^shape_female_B1),
    Female_8_B1  = exp(-(8/Female_lambda_B1)^shape_female_B1),
    Female_9_B1  = exp(-(9/Female_lambda_B1)^shape_female_B1),
    Female_10_B1  = exp(-(10/Female_lambda_B1)^shape_female_B1),
    Female_11_B1  = exp(-(11/Female_lambda_B1)^shape_female_B1),
    Female_12_B1  = exp(-(12/Female_lambda_B1)^shape_female_B1),
    Female_13_B1  = exp(-(13/Female_lambda_B1)^shape_female_B1),
    Female_14_B1  = exp(-(14/Female_lambda_B1)^shape_female_B1),
    Female_15_B1  = exp(-(15/Female_lambda_B1)^shape_female_B1),
    Female_16_B1  = exp(-(16/Female_lambda_B1)^shape_female_B1),
    Female_17_B1  = exp(-(17/Female_lambda_B1)^shape_female_B1),
    Female_18_B1  = exp(-(18/Female_lambda_B1)^shape_female_B1),
    Female_19_B1  = exp(-(19/Female_lambda_B1)^shape_female_B1),
    Female_20_B1  = exp(-(20/Female_lambda_B1)^shape_female_B1),
    Female_21_B1 = exp(-(21/Female_lambda_B1)^shape_female_B1),
    Female_22_B1 = exp(-(22/Female_lambda_B1)^shape_female_B1),
    Female_23_B1 = exp(-(23/Female_lambda_B1)^shape_female_B1),
    Female_24_B1 = exp(-(24/Female_lambda_B1)^shape_female_B1),
    Female_25_B1 = exp(-(25/Female_lambda_B1)^shape_female_B1),
    Female_26_B1 = exp(-(26/Female_lambda_B1)^shape_female_B1),
    Female_27_B1 = exp(-(27/Female_lambda_B1)^shape_female_B1),
    Female_28_B1 = exp(-(28/Female_lambda_B1)^shape_female_B1),
    Female_29_B1 = exp(-(29/Female_lambda_B1)^shape_female_B1),
    Male_0_B1     = exp(-(0/Male_lambda_B1)^shape_male_B1),
    Male_1_B1     = exp(-(1/Male_lambda_B1)^shape_male_B1),
    Male_2_B1     = exp(-(2/Male_lambda_B1)^shape_male_B1),
    Male_3_B1     = exp(-(3/Male_lambda_B1)^shape_male_B1),
    Male_4_B1     = exp(-(4/Male_lambda_B1)^shape_male_B1),
    Male_5_B1     = exp(-(5/Male_lambda_B1)^shape_male_B1),
    Male_6_B1     = exp(-(6/Male_lambda_B1)^shape_male_B1),
    Male_7_B1     = exp(-(7/Male_lambda_B1)^shape_male_B1),
    Male_8_B1     = exp(-(8/Male_lambda_B1)^shape_male_B1),
    Male_9_B1     = exp(-(9/Male_lambda_B1)^shape_male_B1),
    Male_10_B1    = exp(-(10/Male_lambda_B1)^shape_male_B1),
    Male_11_B1    = exp(-(11/Male_lambda_B1)^shape_male_B1),
    Male_12_B1    = exp(-(12/Male_lambda_B1)^shape_male_B1),
    Male_13_B1    = exp(-(13/Male_lambda_B1)^shape_male_B1),
    Male_14_B1    = exp(-(14/Male_lambda_B1)^shape_male_B1),
    Male_15_B1    = exp(-(15/Male_lambda_B1)^shape_male_B1),
    Male_16_B1    = exp(-(16/Male_lambda_B1)^shape_male_B1),
    Male_17_B1    = exp(-(17/Male_lambda_B1)^shape_male_B1),
    Male_18_B1    = exp(-(18/Male_lambda_B1)^shape_male_B1),
    Male_19_B1    = exp(-(19/Male_lambda_B1)^shape_male_B1),
    Male_20_B1    = exp(-(20/Male_lambda_B1)^shape_male_B1),
    Male_21_B1 = exp(-(21/Male_lambda_B1)^shape_male_B1),
    Male_22_B1 = exp(-(22/Male_lambda_B1)^shape_male_B1),
    Male_23_B1 = exp(-(23/Male_lambda_B1)^shape_male_B1),
    Male_24_B1 = exp(-(24/Male_lambda_B1)^shape_male_B1),
    Male_25_B1 = exp(-(25/Male_lambda_B1)^shape_male_B1),
    Male_26_B1 = exp(-(26/Male_lambda_B1)^shape_male_B1),
    Male_27_B1 = exp(-(27/Male_lambda_B1)^shape_male_B1),
    Male_28_B1 = exp(-(28/Male_lambda_B1)^shape_male_B1),
    Male_29_B1 = exp(-(29/Male_lambda_B1)^shape_male_B1),
    # Block 2
    Control_0_B2  = exp(-(0/Control_lambda_B2)^shape_control_B2),  
    Control_1_B2  = exp(-(1/Control_lambda_B2)^shape_control_B2),
    Control_2_B2  = exp(-(2/Control_lambda_B2)^shape_control_B2),
    Control_3_B2  = exp(-(3/Control_lambda_B2)^shape_control_B2),
    Control_4_B2  = exp(-(4/Control_lambda_B2)^shape_control_B2),
    Control_5_B2  = exp(-(5/Control_lambda_B2)^shape_control_B2),
    Control_6_B2  = exp(-(6/Control_lambda_B2)^shape_control_B2),
    Control_7_B2  = exp(-(7/Control_lambda_B2)^shape_control_B2),
    Control_8_B2 = exp(-(8/Control_lambda_B2)^shape_control_B2),
    Control_9_B2 = exp(-(9/Control_lambda_B2)^shape_control_B2),
    Control_10_B2 = exp(-(10/Control_lambda_B2)^shape_control_B2),
    Control_11_B2 = exp(-(11/Control_lambda_B2)^shape_control_B2),
    Control_12_B2 = exp(-(12/Control_lambda_B2)^shape_control_B2),
    Control_13_B2 = exp(-(13/Control_lambda_B2)^shape_control_B2),
    Control_14_B2 = exp(-(14/Control_lambda_B2)^shape_control_B2),
    Control_15_B2 = exp(-(15/Control_lambda_B2)^shape_control_B2),
    Control_16_B2 = exp(-(16/Control_lambda_B2)^shape_control_B2),
    Control_17_B2 = exp(-(17/Control_lambda_B2)^shape_control_B2),
    Control_18_B2 = exp(-(18/Control_lambda_B2)^shape_control_B2),
    Control_19_B2 = exp(-(19/Control_lambda_B2)^shape_control_B2),
    Control_20_B2 = exp(-(20/Control_lambda_B2)^shape_control_B2),
    Control_21_B2 = exp(-(21/Control_lambda_B2)^shape_control_B2),
    Control_22_B2 = exp(-(22/Control_lambda_B2)^shape_control_B2),
    Control_23_B2 = exp(-(23/Control_lambda_B2)^shape_control_B2),
    Control_24_B2 = exp(-(24/Control_lambda_B2)^shape_control_B2),
    Control_25_B2 = exp(-(25/Control_lambda_B2)^shape_control_B2),
    Control_26_B2 = exp(-(26/Control_lambda_B2)^shape_control_B2),
    Control_27_B2 = exp(-(27/Control_lambda_B2)^shape_control_B2),
    Control_28_B2 = exp(-(28/Control_lambda_B2)^shape_control_B2),
    Control_29_B2 = exp(-(29/Control_lambda_B2)^shape_control_B2),
    Female_0_B2  = exp(-(0/Female_lambda_B2)^shape_female_B2),
    Female_1_B2  = exp(-(1/Female_lambda_B2)^shape_female_B2),
    Female_2_B2  = exp(-(2/Female_lambda_B2)^shape_female_B2),
    Female_3_B2  = exp(-(3/Female_lambda_B2)^shape_female_B2),
    Female_4_B2  = exp(-(4/Female_lambda_B2)^shape_female_B2),
    Female_5_B2  = exp(-(5/Female_lambda_B2)^shape_female_B2),
    Female_6_B2  = exp(-(6/Female_lambda_B2)^shape_female_B2),
    Female_7_B2  = exp(-(7/Female_lambda_B2)^shape_female_B2),
    Female_8_B2  = exp(-(8/Female_lambda_B2)^shape_female_B2),
    Female_9_B2  = exp(-(9/Female_lambda_B2)^shape_female_B2),
    Female_10_B2  = exp(-(10/Female_lambda_B2)^shape_female_B2),
    Female_11_B2  = exp(-(11/Female_lambda_B2)^shape_female_B2),
    Female_12_B2  = exp(-(12/Female_lambda_B2)^shape_female_B2),
    Female_13_B2  = exp(-(13/Female_lambda_B2)^shape_female_B2),
    Female_14_B2  = exp(-(14/Female_lambda_B2)^shape_female_B2),
    Female_15_B2  = exp(-(15/Female_lambda_B2)^shape_female_B2),
    Female_16_B2  = exp(-(16/Female_lambda_B2)^shape_female_B2),
    Female_17_B2  = exp(-(17/Female_lambda_B2)^shape_female_B2),
    Female_18_B2  = exp(-(18/Female_lambda_B2)^shape_female_B2),
    Female_19_B2  = exp(-(19/Female_lambda_B2)^shape_female_B2),
    Female_20_B2  = exp(-(20/Female_lambda_B2)^shape_female_B2),
    Female_21_B2 = exp(-(21/Female_lambda_B2)^shape_female_B2),
    Female_22_B2 = exp(-(22/Female_lambda_B2)^shape_female_B2),
    Female_23_B2 = exp(-(23/Female_lambda_B2)^shape_female_B2),
    Female_24_B2 = exp(-(24/Female_lambda_B2)^shape_female_B2),
    Female_25_B2 = exp(-(25/Female_lambda_B2)^shape_female_B2),
    Female_26_B2 = exp(-(26/Female_lambda_B2)^shape_female_B2),
    Female_27_B2 = exp(-(27/Female_lambda_B2)^shape_female_B2),
    Female_28_B2 = exp(-(28/Female_lambda_B2)^shape_female_B2),
    Female_29_B2 = exp(-(29/Female_lambda_B2)^shape_female_B2),
    Male_0_B2     = exp(-(0/Male_lambda_B2)^shape_male_B2),
    Male_1_B2     = exp(-(1/Male_lambda_B2)^shape_male_B2),
    Male_2_B2     = exp(-(2/Male_lambda_B2)^shape_male_B2),
    Male_3_B2     = exp(-(3/Male_lambda_B2)^shape_male_B2),
    Male_4_B2     = exp(-(4/Male_lambda_B2)^shape_male_B2),
    Male_5_B2     = exp(-(5/Male_lambda_B2)^shape_male_B2),
    Male_6_B2     = exp(-(6/Male_lambda_B2)^shape_male_B2),
    Male_7_B2     = exp(-(7/Male_lambda_B2)^shape_male_B2),
    Male_8_B2     = exp(-(8/Male_lambda_B2)^shape_male_B2),
    Male_9_B2     = exp(-(9/Male_lambda_B2)^shape_male_B2),
    Male_10_B2    = exp(-(10/Male_lambda_B2)^shape_male_B2),
    Male_11_B2    = exp(-(11/Male_lambda_B2)^shape_male_B2),
    Male_12_B2    = exp(-(12/Male_lambda_B2)^shape_male_B2),
    Male_13_B2    = exp(-(13/Male_lambda_B2)^shape_male_B2),
    Male_14_B2    = exp(-(14/Male_lambda_B2)^shape_male_B2),
    Male_15_B2    = exp(-(15/Male_lambda_B2)^shape_male_B2),
    Male_16_B2    = exp(-(16/Male_lambda_B2)^shape_male_B2),
    Male_17_B2    = exp(-(17/Male_lambda_B2)^shape_male_B2),
    Male_18_B2    = exp(-(18/Male_lambda_B2)^shape_male_B2),
    Male_19_B2    = exp(-(19/Male_lambda_B2)^shape_male_B2),
    Male_20_B2    = exp(-(20/Male_lambda_B2)^shape_male_B2),
    Male_21_B2 = exp(-(21/Male_lambda_B2)^shape_male_B2),
    Male_22_B2 = exp(-(22/Male_lambda_B2)^shape_male_B2),
    Male_23_B2 = exp(-(23/Male_lambda_B2)^shape_male_B2),
    Male_24_B2 = exp(-(24/Male_lambda_B2)^shape_male_B2),
    Male_25_B2 = exp(-(25/Male_lambda_B2)^shape_male_B2),
    Male_26_B2 = exp(-(26/Male_lambda_B2)^shape_male_B2),
    Male_27_B2 = exp(-(27/Male_lambda_B2)^shape_male_B2),
    Male_28_B2 = exp(-(28/Male_lambda_B2)^shape_male_B2),
    Male_29_B2 = exp(-(29/Male_lambda_B2)^shape_male_B2)) %>% 
  select(-c(contains(c("shape", "lambda"))))

Weibull_extinction_estimates_long <-
  Weibull_survival_curve %>% 
  pivot_longer(cols = everything(), names_to = "Evolution treatment", values_to = "Prop_subpopulations_surviving") %>% 
  separate(`Evolution treatment`, into = c("Evolution treatment", "Generation", "Block"), sep = "_") %>% 
    mutate(`Evolution treatment` = case_when(
    `Evolution treatment` == "Female" ~ "Female-limited",
    `Evolution treatment` == "Male" ~ "Male-limited",
    `Evolution treatment` == "Control" ~ "Control"
  ))

\(~\)

Create Figure 1

Make panel a of Figure 1

# values from Falconer and Mackay 1996 pg 90

Inbreeding_coefs <-
  tibble(Generation = 0:20,
         Probability_homozygous = c(0, 0.25, 0.375, 0.5, 0.594, 0.672, 0.734, 0.785, 0.826,
                                    0.859, 0.886, 0.908, 0.926, 0.94, 0.951, 0.961, 0.968, 0.974,
                                    0.979, 0.983, 0.986),
         Probability_pop_fixation = c(0, 0, 0.063, 0.172, 0.293, 0.409, 0.512, 0.601, 0.675, 0.736, 0.785, 
                                      0.826, 0.859, 0.886, 0.908, 0.925, 0.94, 0.951, 0.96, 0.968, 0.975)) %>% 
  mutate(single_locus_heterozygosity = 1 - Probability_homozygous,
         single_locus_not_fixed = 1 - Probability_pop_fixation) 

# for the plot annotations

arrows <- 
  tibble(
    x1 = 3.2,
    x2 = 5.6,
    y1 = 0.28, 
    y2 = 0.49)

# Block 1

weibull_surv_plot_B1 <- 
  Weibull_extinction_estimates_long %>% 
  filter(Block == "B1") %>% 
  group_by(`Evolution treatment`, Generation) %>% 
  tidybayes::median_qi(Prop_subpopulations_surviving, .width = 0.5) %>% 
  mutate(Generation = as.numeric(Generation)) %>% 
  arrange(Generation) %>% 
  # plot!
  ggplot(aes(x = Generation)) +
  geom_line(data = Inbreeding_coefs, aes(y = single_locus_not_fixed), linetype = 3, 
            linewidth = 2, alpha = 1) +
  geom_ribbon(aes(ymin = .lower, ymax = .upper, fill = `Evolution treatment`),
              alpha = 1/2) +
  geom_line(aes(y = Prop_subpopulations_surviving, color = `Evolution treatment`), linetype =5, linewidth = 0.8) +
  
  annotate("text", x = 3.2, y = 0.26, size = 4, label = "Single locus prob. of heterozygosity") +
  geom_curve(
    data = arrows, aes(x = x1, y = y1, xend = x2, yend = y2),
    arrow = arrow(length = unit(0.08, "inch")), size = 0.75,
    color = "gray20", curvature = -0.3) +
  
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_color_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_x_continuous(breaks = c(0, 5, 10, 15, 20, 25, 30), expand = expansion(mult = c(0.01, 0.01)), limits = c(0, 20)) +
  scale_y_continuous(breaks = c(0, 0.25, .5, 0.75, 1), limits = 0:1, expand = expansion(mult = c(0.01, 0.01))) +
  labs(x = "Generations of inbreeding", y = "Proportion of surviving subpopulations", fill = "Inheritance treatment") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.background = element_rect(fill='transparent'), #transparent legend bg
        legend.box.background = element_rect(fill='transparent', colour = 'transparent'), #transparent legend panel
        legend.position = c(.95, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6),
        text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11))

We can also plot the mean generations until extinction for each evolution treatment. Some data wrangling is first needed.

new_data <- expand_grid(
  Evolution_treatment = extinction_data_wrangled$Evolution_treatment,
  Block = 1:2) %>% 
  distinct(Evolution_treatment, Block) %>%
  mutate(key = paste("V", 1:n(), sep = ""))

weibull_estimates <- 
  fitted(extinction_model_sm, newdata = new_data,
         re_formula = NA, summary = F) %>%  #robust = T) %>% 
  as_tibble() %>% 
  rename(`Female-limited_1` = V1, `Female-limited_2` = V2, `Male-limited_1` = V3, `Male-limited_2` = V4, Control_1 = V5, Control_2 = V6)

mean_weibull_estimates <- 
  weibull_estimates %>% 
  pivot_longer(cols = 1:6, names_to = "Evolution treatment", values_to = "generations") %>% 
  separate(col = `Evolution treatment`, into = c("Evolution treatment", "Block"), sep = "_")


# calculate contrasts

weibull_contrasts_B1 <-
  weibull_estimates %>% 
  mutate(`Female - Control` = `Female-limited_1` - Control_1,
         `Male - Female` = `Male-limited_1` - `Female-limited_1`,
         `Male - Control` = `Male-limited_1` - Control_1) %>% 
  select(-c(`Male-limited_1`, Control_1, `Female-limited_1`,
            `Male-limited_2`, Control_2, `Female-limited_2`)) %>% 
  pivot_longer(cols = 1:3, names_to = "Contrast", values_to = "generation_diff")

weibull_contrasts_B2 <-
  weibull_estimates %>% 
  mutate(`Female - Control` = `Female-limited_2` - Control_2,
         `Male - Female` = `Male-limited_2` - `Female-limited_2`,
         `Male - Control` = `Male-limited_2` - Control_2) %>% 
  select(-c(`Male-limited_1`, Control_1, `Female-limited_1`,
            `Male-limited_2`, Control_2, `Female-limited_2`)) %>% 
  pivot_longer(cols = 1:3, names_to = "Contrast", values_to = "generation_diff")

Create panels b and c of Figure 1

# plot the means

# block 1

ext_p1_B1 <- 
  mean_weibull_estimates %>% 
  filter(Block == "1") %>% 
  ggplot(aes(x = generations, y = `Evolution treatment`)) +
  stat_halfeye(aes(fill = `Evolution treatment`), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals + # width indicates the uncertainty intervals: here we have 66% and 95% intervals+
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x = "Generations till extinction", y = "Inheritance treatment") +
  scale_x_continuous(breaks=seq(4, 12, 1), limits = c(4, 12)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(), 
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

# plot the contrasts

ext_p2_B1 <- 
  weibull_contrasts_B1 %>% 
  ggplot(aes(x = generation_diff, y = fct_relevel(Contrast, "Female - Control", "Male - Female", "Male - Control"))) +
  stat_halfeye(aes(fill = Contrast), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5) + 
  scale_fill_manual(values = c(carto_pal(7, "Peach")[2], carto_pal(7, "Purp")[1], carto_pal(7, "TealGrn")[1])) +
  geom_vline(xintercept = 0, linetype = 2, colour = "black", size = 1) +
  labs(x = "Diff. in generations till extinction", y = "Treatment contrast") +
  scale_x_continuous(breaks=seq(-4, 6, 2)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(),
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

We can also estimate the difference between evolutionary treatments in the proportion of subpopulations extant in each generation. Below we calculate each contrast and make panels d, e and f

# Block 1

Difference_gens_B1 <-
  Weibull_survival_curve %>% 
  select(contains("B1")) %>% 
  mutate(G1_diff.c = Male_1_B1 - Control_1_B1,
         G1_diff.f = Male_1_B1 - Female_1_B1,
         G1_diff.fc = Female_1_B1 - Control_1_B1,
         G2_diff.c = Male_2_B1 - Control_2_B1,
         G2_diff.f = Male_2_B1 - Female_2_B1,
         G2_diff.fc = Female_2_B1 - Control_2_B1,
         G3_diff.c = Male_3_B1 - Control_3_B1,
         G3_diff.f = Male_3_B1 - Female_3_B1,
         G3_diff.fc = Female_3_B1 - Control_3_B1,
         G4_diff.c = Male_4_B1 - Control_4_B1,
         G4_diff.f = Male_4_B1 - Female_4_B1,
         G4_diff.fc = Female_4_B1 - Control_4_B1,
         G5_diff.c = Male_5_B1 - Control_5_B1,
         G5_diff.f = Male_5_B1 - Female_5_B1,
         G5_diff.fc = Female_5_B1 - Control_5_B1,
         G6_diff.c = Male_6_B1 - Control_6_B1,
         G6_diff.f = Male_6_B1 - Female_6_B1,
         G6_diff.fc = Female_6_B1 - Control_6_B1,
         G7_diff.c = Male_7_B1 - Control_7_B1,
         G7_diff.f = Male_7_B1 - Female_7_B1,
         G7_diff.fc = Female_7_B1 - Control_7_B1,
         G8_diff.c = Male_8_B1 - Control_8_B1,
         G8_diff.f = Male_8_B1 - Female_8_B1,
         G8_diff.fc = Female_8_B1 - Control_8_B1,
         G9_diff.c = Male_9_B1 - Control_9_B1,
         G9_diff.f = Male_9_B1 - Female_9_B1,
         G9_diff.fc = Female_9_B1 - Control_9_B1,
         G10_diff.c = Male_10_B1 - Control_10_B1,
         G10_diff.f = Male_10_B1 - Female_10_B1,
         G10_diff.fc = Female_10_B1 - Control_10_B1,
         G11_diff.c = Male_11_B1 - Control_11_B1,
         G11_diff.f = Male_11_B1 - Female_11_B1,
         G11_diff.fc = Female_11_B1 - Control_11_B1,
         G12_diff.c = Male_12_B1 - Control_12_B1,
         G12_diff.f = Male_12_B1 - Female_12_B1,
         G12_diff.fc = Female_12_B1 - Control_12_B1,
         G13_diff.c = Male_13_B1 - Control_13_B1,
         G13_diff.f = Male_13_B1 - Female_13_B1,
         G13_diff.fc = Female_13_B1 - Control_13_B1,
         G14_diff.c = Male_14_B1 - Control_14_B1,
         G14_diff.f = Male_14_B1 - Female_14_B1,
         G14_diff.fc = Female_14_B1 - Control_14_B1,
         G15_diff.c = Male_15_B1 - Control_15_B1,
         G15_diff.f = Male_15_B1 - Female_15_B1,
         G15_diff.fc = Female_15_B1 - Control_15_B1,
         G16_diff.c = Male_16_B1 - Control_16_B1,
         G16_diff.f = Male_16_B1 - Female_16_B1,
         G16_diff.fc = Female_16_B1 - Control_16_B1,
         G17_diff.c = Male_17_B1 - Control_17_B1,
         G17_diff.f = Male_17_B1 - Female_17_B1,
         G17_diff.fc = Female_17_B1 - Control_17_B1,
         G18_diff.c = Male_18_B1 - Control_18_B1,
         G18_diff.f = Male_18_B1 - Female_18_B1,
         G18_diff.fc = Female_18_B1 - Control_18_B1,
         G19_diff.c = Male_19_B1 - Control_19_B1,
         G19_diff.f = Male_19_B1 - Female_19_B1,
         G19_diff.fc = Female_19_B1 - Control_19_B1,
         G20_diff.c = Male_20_B1 - Control_20_B1,
         G20_diff.f = Male_20_B1 - Female_20_B1,
         G20_diff.fc = Female_20_B1 - Control_20_B1) %>% 
        #G21_diff.c = Male_21_B1 - Control_21_B1,
        #G21_diff.f = Male_21_B1 - Female_21_B1,
        #G21_diff.fc = Female_21_B1 - Control_21_B1,
        #G22_diff.c = Male_22_B1 - Control_22_B1,
        #G22_diff.f = Male_22_B1 - Female_22_B1,
        #G22_diff.fc = Female_22_B1 - Control_22_B1,
        #G23_diff.c = Male_23_B1 - Control_23_B1,
        #G23_diff.f = Male_23_B1 - Female_23_B1,
        #G23_diff.fc = Female_23_B1 - Control_23_B1,
        #G24_diff.c = Male_24_B1 - Control_24_B1,
        #G24_diff.f = Male_24_B1 - Female_24_B1,
        #G24_diff.fc = Female_24_B1 - Control_24_B1,
        #G25_diff.c = Male_25_B1 - Control_25_B1,
        #G25_diff.f = Male_25_B1 - Female_25_B1,
        #G25_diff.fc = Female_25_B1 - Control_25_B1,
        #G26_diff.c = Male_26_B1 - Control_26_B1,
        #G26_diff.f = Male_26_B1 - Female_26_B1,
        #G26_diff.fc = Female_26_B1 - Control_26_B1,
        #G27_diff.c = Male_27_B1 - Control_27_B1,
        #G27_diff.f = Male_27_B1 - Female_27_B1,
        #G27_diff.fc = Female_27_B1 - Control_27_B1,
        #G28_diff.c = Male_28_B1 - Control_28_B1,
        #G28_diff.f = Male_28_B1 - Female_28_B1,
        #G28_diff.fc = Female_28_B1 - Control_28_B1,
        #G29_diff.c = Male_2_B1 - Control_29_B1,
        #G29_diff.f = Male_29_B1 - Female_29_B1,
        #G29_diff.fc = Female_29_B1 - Control_29_B1) %>% 
  select(starts_with("G")) %>% 
  pivot_longer(cols = everything(), names_to = "Difference contrast", values_to = "survival_diff") %>% 
  separate(`Difference contrast`, into = c("Generation", "Difference contrast"), sep = "_") %>% 
  mutate(Generation = as.numeric(str_remove(Generation, "G")))


# Make the three plots

Leaf_plot_mc_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.c") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProp. surv subpopulations",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8)) 

Leaf_plot_mf_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.f") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProp. surv subpopulations",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_fc_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.fc") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProp. surv subpopulations",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Combine the 6 panels

(weibull_surv_plot_B1 / (ext_p1_B1 + ext_p2_B1)) / (Leaf_plot_mc_B1 + Leaf_plot_mf_B1 + Leaf_plot_fc_B1) +
  plot_annotation(tag_levels = 'a') + 
  plot_layout(heights = c(1.5, 1, 1))

Figure 1. Panel a shows extinction trajectories under increasing stress from inbreeding. Bands are 50% credible intervals to aid visual inspection. The black dotted line is the probability that a randomly selected autosomal locus remains heterozygous. b shows the posterior distribution for the number of generations that sub-populations descended from each inheritance treatment survived inbreeding exposure. The white point shows the median with associated 66 and 95% credible intervals c shows the distribution of the difference between each treatment in generations survived. d-f show the distribution of the difference between each treatment in generations survived, estimated separately for each generation of inbreeding. The innermost colour band approximates the median, while the middle and outermost bars show 66 and 95% credible intervals.

\(~\)

Productivity analysis

\(~\)

We have several hypotheses that we test with the productivity data. First, productivity should be negatively correlated with the number of generations inbreeding occurs, due to inbreeding depression. As mentioned above, this effect should be strongest in the first ~10 generations of the experiment, during which full-sibling inbreeding should have the largest effects on genome wide heterozygosity. After this point, the inbreeding coefficient will be 0.89, while over the next 10 generations it should only increase by a further 0.1 to 0.99. Hence, we expect productivity to stabilise between the 10th and 20th generations, assuming the subpopulation is still extant. Second, subpopulations carrying autosomes that have responded to selection on males should exhibit a smaller drop in productivity compared with subpopulations carrying the female-adapted or control autosomes, because they have a history of stronger selection that should, in theory, have purged the genome of recessive deleterious alleles.

Load in the data

data <-
  read_csv("Data/Productivity_data.csv") %>% 
  mutate(Week = case_when(
    Block == 1 ~ Generation,
    Block == 2 ~ Generation + 9))

Productivity_data <- 
  left_join(
    data,
    
    data %>% 
      distinct(Cross, Replicate) %>% 
      rowid_to_column("subpopulation")
  ) %>% 
  select(subpopulation, everything()) %>% 
  mutate(across(1:7, as.factor),
         Week = as.factor(Week),
         Collection_window_offspring = Female_offspring + Male_offspring,
         Pre_window_offspring = Pre_window_female_offspring + Pre_window_male_offspring,
         Total_female_offspring = Female_offspring + Pre_window_female_offspring,
         Total_male_offspring = Male_offspring + Pre_window_male_offspring,
         Total_offspring = Total_female_offspring + Total_male_offspring) %>% 
  # In one generation of the experiment (b1 = G24 & B2 = G15) sibling pairs were setup a day early and removed from their vials at the regular time, meaning that they had an extra day to produce offspring. To correct for this we multiply offspring counts by 0.75.
  mutate(Collection_window_offspring = if_else(Count_conditions == "Extra day", 
                                               round(Collection_window_offspring * 0.75),  Collection_window_offspring),
         # note that because everything is moved a day early, pre-window offspring counts will still be inflated even after this correction
         Pre_window_offspring = if_else(Count_conditions == "Extra day", 
                                        round(Pre_window_offspring * 0.75),  Pre_window_offspring))
  
# Combine with mortality and extinction data to filter out vials that went extinct because of female mortality

Productivity_mortality <-
  left_join(
    Productivity_data %>% 
      filter(Generation < 21), #%>% only include data collected on the first 20 generations of inbreeding (block 2's endpoint)
    mortality_data %>% select(subpopulation, Generation, Female_mortality)
  )

# We also include a column that specifies if a subpopulation was extinct. This means we can easily remove 0 values from the data if required. We can use the `extinction_data_wrangled$Gens_to_extinct` column to help us here. 

Productivity_data_clean <-
  left_join(
    Productivity_mortality,  
    extinction_data_wrangled %>% 
      select(subpopulation, Gens_to_extinct, Censored_mortality)
  ) %>% 
  mutate(Vial_setup = if_else(Generation > Gens_to_extinct, "No", "Yes")) %>% 
  filter(Collection_window_offspring != "NA")

# remove mortality events and their consequences in later generations

Productivity_data_clean_2 <-
  Productivity_data_clean %>%
  mutate(Collection_window_offspring = case_when(
    Censored_mortality == 1 & Vial_setup == "No" ~ NA_real_,
    TRUE ~ Collection_window_offspring)) %>% 
  filter(!is.na(Collection_window_offspring),
         Female_mortality != 1 | is.na(Female_mortality))


# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'Productivity_data_clean_2')),
      pageLength = 8500
    )
  )
}

my_data_table(Productivity_data_clean %>% 
                select(Mother_strain, Father_strain, Cross, subpopulation, Block, Week, Generation, Treatment, Vial_setup, Count_conditions, Female_offspring, Male_offspring, Collection_window_offspring, Pre_window_female_offspring, Pre_window_male_offspring, Pre_window_offspring, Total_female_offspring, Total_male_offspring, Total_offspring))

Column explanations

Mother strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same Evolution_treatment. This column shows the strain that the founding female of the subpopulation was derived from.

Father strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same evolution treatment. This column shows the strain that the founding male of the subpopulation was derived from.

Cross: an identifying ID for each of the 36 combinations of Mother strain and Father strain.

subpopulation: lines of flies founded by single inseminated females in generation zero. We generated the next generation of each subpopulation by crossing a single full-sibling dyad.

Block: the experiment was run in 2 distinct blocks, using flies separated by 9 generations. Block 1 ran for 29 generations, whereas Block 2 ran for 20 generations.

Week: the week that the generation of each block was conducted in. Note that blocks overlap between weeks 9-29.

Generation: the generation of the extinction assay, ranging from 1 to 20.

Treatment: the strains had been exposed to one of three evolutionary conditions for 20-29 generations: a female-limited response to selection, a male-limited response and a control condition where an evolutionary response occurred in both sexes.

Vial setup: specifies whether a vial was setup for a given subpopulation in a given generation. Vials were not setup when the subpopulation was extinct, or when it could no longer be included in the experiment due to escape/ handling error.

Count_conditions: Normal indicates that the breeding window lasted the standard three days. Extra day indicates the breeding pair were left in the vial for an extra day. This occurred during generation 15 of the second experimental block.

Female_offspring: the number of adult females produced by the breeding pair that eclosed during the four-day collection window

Male_offspring: as above, but for male offspring.

Collection_window_offspring: the sum of Female_offspring and Male_offspring.

Pre_window_female_offspring: females progeny that eclosed prior to the collection window opening.

Pre_window_male_offspring: as above, but for male offspring.

Pre_window_offspring: the sum of Pre_window_female_offspring and Pre_window_male_offspring.

Total_female_offspring: the sum of Female_offspring and Pre_window_female_offspring.

Total_male_offspring: as above, but for male offspring.

Total_offspring: the total number of offspring produced, summed across the sexes and the pre-window and within-window collections.

\(~\)

Do offspring emerge prior to day 10 throughout the experiment?

  Productivity_data_clean %>% 
  ggplot(aes(x = Generation, y = Pre_window_offspring/Total_offspring)) +
  geom_jitter(aes(size = Total_offspring), colour = met.brewer("OKeeffe2")[2], fill = met.brewer("OKeeffe2")[3], width = 0.2, 
              shape = 21, stroke =1, alpha = 0.25) +
  scale_size(range = c(0, 5), name = "Total offspring") +
  scale_y_continuous(limits = c(0,1), expand = expansion(mult = c(0.01, 0.01))) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20)) +
  labs(y = "Prop. offspring eclosing prior to day 10", 
       x = "Generation of inbreeding",
       ) +
  theme(text = element_text(size = 14),
        legend.position = "bottom")

Figure S3. Raw proportion of productivity that occurred prior to the eclosion window, for the first 20 generations of the experiment.

\(~\)

Testing for our casual effect

\(~\)

Modelling approach

As mentioned above, we have strong expectations for how full-sibling inbreeding should affect productivity. Decreasing genome-wide heterozygosity and the expression of recessive deleterious alleles that comes with this should follow a pattern of exponential decay. This non-linear process can be modelled using the brms non-linear syntax.

Here we model the productivity at generation \(t\) via the function \(a - e^{\lambda t}\) where \(a\) and \(\lambda\) are parameters that control the initial productivity and the rate of its decay as generations of inbreeding progress. We force \(a\) to be positive using the exp() function, which expresses it on the exponential scale. Large \(a\) indicates higher starting productivity at generation 0 (we started observation at generation 1, the productivity for which is given by \(a - e^{\lambda}\)). Positive values of \(\lambda\) indicate that productivity declines with inbreeding, which is our strong expectation and clearly the case following inspection of the raw data (see Figure SX).

We model inbreeding depression while including zero values for all rows where a subpopulation was extinct. This helps combat underestimation of the decay parameter, caused by the non-random extinction of subpopulations, where high fitness subpopulations become over-represented as the generations of inbreeding progress (i.e. selection).

Fixed and random effects

In the brms non-linear syntax, different formulas can be fit for each parameter. We fit the same fixed effect for \(a\) and \(\lambda\): Evolution treatment. We fit subpopulation as a random effect to account for repeated measurements taken on each subpopulation for \(a\), but are unable to do this for \(\lambda\), as individual subpopulation productivity curves are highly heteroskedastic, and are skewed by extinction events. To minimise pseudoreplication for \(\lambda\), we fit Cross as a random effect, as we do for the extinction data. We also fit Week as a random effect for both parameters; this controls for environmental variation between generations.

Priors

We fit moderately informative priors, with the aim to regularise our posterior estimates and improve model fitting by ruling out non-sensical values. Note that priors are particularly important when fitting non-linear models.

Note that \(\alpha\) related priors are expressed on the exponential scale.

\(\alpha\) (initial productivity) ~ Normal(\(\mu\) = 4.2, \(\sigma\) = 0.25)

\(\lambda\) (the rate of decay) ~ Gamma(shape = 0.8, rate = 4)

\(\sigma\) for \(\alpha\) ~ Gamma(shape = 2, rate = 1.5)

\(\sigma\) for \(\lambda\) ~ Gamma(shape = 0.25, rate = 2)

\(~\)

Simulate the curve, with the priors we will specify

Prior predictive simulation for the productivity decline model. The plot shows the results from 100 prior draws.

n <- 1e4

# define the x-axis breaks
at <- 1:20

# how many prior draws would you like?
n_draws <- 200

# simulate
set.seed(16)

prior <-
  tibble(index = 1:n,
         a   = rnorm(n, mean = 4.2, sd = 0.25),
         lambda = rgamma(n, 0.8, 4)) %>% 
  slice_sample(n = n_draws) %>% 
  expand(nesting(index, a, lambda),
         Generation = seq(from = 0, to = 20, length.out = 1e2)) %>% 
  mutate(productivity = exp(a - lambda * Generation)) 


prior %>% 
  ggplot(aes(x = Generation, y = productivity, group = index)) +
  geom_line(size = 1/2, alpha = 1/4, colour = met.brewer("Hiroshige")[2]) +
  theme_tidybayes() +
  scale_y_continuous(limits = c(0,200), expand = expansion(mult = c(0, .1))) +
  scale_x_continuous(limits = c(0,20), expand = c(0, 0)) +
  labs(y = "subpopulation productivity", x = "Generation of inbreeding") +
  theme(text = element_text(size = 14))

\(~\)

Fit the non-linear model

nonlinear_productivity <- 
  brm(bf(Collection_window_offspring ~ exp(a - (lambda * Generation)),
         a ~ 1 + Treatment + (1|Week) + (1|subpopulation), 
         lambda ~ 1 + Treatment + (1|Week) + (1|Cross), 
         nl = TRUE),
      data = Productivity_data_clean,
      prior = c(prior(normal(4.2, 0.25), class = b, coef = Intercept, nlpar = "a"),
                prior(normal(0, 0.25), class = b, coef = TreatmentFemale, nlpar = "a"),
                prior(normal(0, 0.25), class = b, coef = TreatmentMale, nlpar = "a"),
                prior(gamma(0.8, 4), class = b, coef = Intercept, nlpar = "lambda"),
                prior(normal(0, 0.2), class = b, coef = TreatmentFemale, nlpar = "lambda"),
                prior(normal(0, 0.2), class = b, coef = TreatmentMale, nlpar = "lambda"),
                prior(gamma(2, 1.5), class = sd, nlpar = "a"),
                prior(gamma(0.25, 2), class = sd, nlpar = "lambda")),
      control = list(adapt_delta = 0.9, max_treedepth = 12), seed = 5,
      iter = 20000, warmup = 5000, chains = 4, cores = 4,
      file = "Fits/non_linear_productivity_model_no_fam")

\(~\)

Build figure 2

\(~\)

new_data <- 
  Productivity_data_clean_2 %>% 
  select(Generation, Treatment) %>%
  distinct() %>%
  mutate(key = paste("V", 1:n(), sep = ""))

preds <- 
  as.data.frame(fitted(nonlinear_productivity, newdata = new_data, re_formula = NA, summary=F)) %>% 
  mutate(draw = 1:n()) %>% 
  gather(key, Collection_window_offspring, -draw) %>% 
  as_tibble() %>% 
  left_join(new_data, by = "key") %>% 
  select(-key) %>% 
    mutate(Treatment = case_when(
    Treatment == "Female" ~ "Female-limited",
    Treatment == "Male" ~ "Male-limited",
    Treatment == "Control" ~ "Control"))

preds_summary <-
  preds %>% 
  group_by(Treatment, Generation) %>%
  median_qi(Collection_window_offspring, .width = 0.5)

nl_p1 <-
  Productivity_data_clean_2 %>% 
  ggplot(aes(x = Generation, y = Collection_window_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.2) +
 # geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7], alpha = 0.4) +
  geom_ribbon(data = preds_summary, 
             aes(ymin = .lower, ymax = .upper, fill = Treatment), alpha = 1/2) +
  geom_line(aes(group = Treatment, colour = Treatment), data = preds_summary,
            size = 1, alpha = 1, linetype = 5) +
  scale_linetype_manual(values = c(1, 2, 3)) +
  scale_colour_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_y_continuous(expand = expansion(mult = c(0.01, 0))) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20), ylim = c(0, 150)) +
  labs(y = "Subpopulation productivity", x = "Generation of inbreeding", fill = "Inheritance treatment") +
  theme(text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11),
        legend.position = c(.99, .99),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6))

\(~\)

Estimating Generation one productivity and \(\lambda\)

Our model estimates \(a\) the initial productivity parameter. This is the productivity in generation 0, which in practice is non-sensical. We instead present productivity in generation one which = \(a - e^{\lambda*1}\).

Gen_1_productivity <-
preds %>% 
  filter(Generation == 1)
  

Initial_productivity_plot <-
  Gen_1_productivity %>% 
  
  ggplot(aes(x = Collection_window_offspring, y = Treatment)) +
  stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5) + 
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x= "Productivity in generation 1", y = "Inheritance treatment") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))



decay_estimates <-  
  as_draws_df(nonlinear_productivity, variable = "^b_lambda", regex = TRUE) %>% 
  mutate(`Female-limited` = b_lambda_Intercept + b_lambda_TreatmentFemale,
         `Male-limited` = b_lambda_Intercept + b_lambda_TreatmentMale,
         Control = b_lambda_Intercept) %>%
 select(`Female-limited`, `Male-limited`, Control) %>% 
  mutate(posterior_sample = 1:n()) %>% 
  gather(Evolution_treatment, lambda, -posterior_sample)
  

decay_plot <-
  decay_estimates %>% 
  ggplot(aes(x = lambda, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white", 
               shape = 21, point_size = 4, stroke = 1.5, scale = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x=expression(paste("Decay rate parameter ", lambda,)), y = NULL) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

Create plots d and e

Difference_gens_productivity <- 
  preds %>% 
  pivot_wider(values_from = "Collection_window_offspring", names_from = "Treatment") %>% 
  mutate(diff.mc = `Male-limited` - Control,
         diff.mf = `Male-limited` - `Female-limited`,
         diff.fc = `Female-limited` - Control) %>% 
  select(Generation, contains("diff")) %>% 
  pivot_longer(cols = contains("diff"), values_to = "productivity_diff", names_to = "Difference contrast") 

# Make the three plots

Leaf_plot_mc_productivity <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mc") %>% 
  ggplot(aes(productivity_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  coord_cartesian(xlim = c(-5, 25)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProductivity diff.",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))


Leaf_plot_mf_productivity <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mf") %>% 
  ggplot(aes(productivity_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  coord_cartesian(xlim = c(-5, 25)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))


Leaf_plot_fc_productivity <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.fc") %>% 
  ggplot(aes(productivity_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  coord_cartesian(xlim = c(-5, 25)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Combine the 6 panels

(nl_p1 / (Initial_productivity_plot + decay_plot)) / (Leaf_plot_mc_productivity + Leaf_plot_mf_productivity + Leaf_plot_fc_productivity) +
  plot_annotation(tag_levels = 'a') + 
  plot_layout(heights = c(1.5, 1, 1))

Figure 2. Panel a shows productivity decline under increasing stress from inbreeding, split by inheritance treatment. Bands are 50% credible intervals to aid visual inspection and circular points show raw productivity counts for each sub-population in each generation. b shows the posterior distribution of productivity in the first generation of the experiment; white points are the median with associated 66 and 95% credible intervals. c shows the distribution of the productivity decay rate for each treatment. d-f show the difference contrasts for productivity in each generation. The innermost colour band approximates the median, while the middle and outermost bars show 66 and 95% credible intervals.

LS0tCnRpdGxlOiAiU2VsZWN0aW9uIGFtb25nIG1hbGVzIHJlZHVjZXMgbXV0YXRpb24gbG9hZCIKYXV0aG9yOiAiVGhvbWFzIEtlYW5leSwgSGVpZGkgV29uZywgWGlhbWVuZyBRaSwgVGhlcmVzYSBKb25lcyBhbmQgTHVrZSBIb2xtYW4iCiNiaWJsaW9ncmFwaHk6ICJzdXBwX3JlZmVyZW5jZXMuYmliIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgZGVwdGg6IDEKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRoZW1lOiB5ZXRpCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBGQUxTRSkKYGBgCgojIExvYWQgcGFja2FnZXMKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyB0aWR5IHN0eWxlIGNvZGluZwpsaWJyYXJ5KGJybXMpICMgQmF5ZXNpYW4gbW9kZWxzCmxpYnJhcnkoYmF5ZXNwbG90KSAjIHByZXR0eSBiYXllcyB2aXN1YWxzCmxpYnJhcnkodGlkeWJheWVzKSAjIEJheWVzaWFuIGFlc3RoZXRpY3MKbGlicmFyeShsb28pICMgdG8gdXNlIGluZm9ybWF0aW9uIGNyaXRlcmlhIGluIGJybXMgbW9kZWxzCmxpYnJhcnkoTWV0QnJld2VyKSAjIGNvbG91cnMKbGlicmFyeShyY2FydG9jb2xvcikgIyBtb3JlIGNvbG91cnMKbGlicmFyeShwYW5kZXIpICMgdGFibGVzCmxpYnJhcnkoa2FibGVFeHRyYSkgIyB0YWJsZXMKbGlicmFyeShwYXRjaHdvcmspICMgcHV0dGluZyBwbG90cyB0b2dldGhlcgpsaWJyYXJ5KERUKSAjIGZvciBzZWFyY2gtIGFuZCBzYXZlYWJsZSB0YWJsZXMKbGlicmFyeShnZ2Rpc3QpICMgZm9yIHJpYmJvbiBwbG90CmxpYnJhcnkocG5nKSAjIHRvIGxvYWQgaW1hZ2VzCmxpYnJhcnkoZ3JpZCkgIyB0byBwbG90IGltYWdlcwpgYGAKCiMgU3VwcGxlbWVudGFyeSBtZXRob2RzCgokfiQKCioqVGFibGUgUzEqKi4gUmVjaXBlIGZvciBmb29kIG1lZGl1bSB1c2VkIGluIG91ciBleHBlcmltZW50LiBUaGUgcHJvdmlkZWQgcXVhbnRpdGllcyBtYWtlIH4gMSBsaXRyZSBvZiBmb29kLgoKYGBge3J9CnRpYmJsZSgiSW5ncmVkaWVudHMiID0gYygiU295IGZsb3VyIiwgIkNvcm5tZWFsIiwgIlllYXN0IiwgIkRleHRyb3NlIiwgIkFnYXIiLCAiV2F0ZXIiLCAiVGVnb3NlcHQiLCAiQWNpZCBtaXggKDQgbUwgb3J0aG9waG9zcGhvcmljIGFjaWQsIDQxIG1MIHByb3Bpb25pYyBhY2lkLCA1NSBtTCB3YXRlciB0byBtYWtlIDEwMCBtTCkiKSwKICAgICAgICJRdWFudGl0eSIgPSBjKCIyMCBnIiwgIjczIGciLCAiMzUgZyIsICI3NSBnIiwgIjYgZyIsICIxMDAwIG1MIiwgIjE3IG1MIiwgIjE0IG1MIikpICU+JSAKICBwYW5kZXIoc3BsaXQuY2VsbCA9IDQwLCBzcGxpdC50YWJsZSA9IEluZikKYGBgCgokfiQKCmBgYHtyfQppbWcgPC0gcmVhZFBORygiRmlndXJlX1MxLnBuZyIpCiAKZ3JpZC5yYXN0ZXIoaW1nKQpgYGAKCioqRmlndXJlIFMxKiouIENyb3NzaW5nIHNjaGVtZSB1c2VkIHRvIGludGVncmF0ZSB0aGUgR0ZQIGNvbnN0cnVjdHMgYW5kIF9hcF5YQV5fIG1hcmtlZCB0cmFuc2xvY2F0ZWQgc2Vjb25kIGFuZCB0aGlyZCBjaHJvbW9zb21lIGJhbGFuY2VycyBpbnRvIHRoZSBMSH5NfiBnZW5ldGljIGJhY2tncm91bmQuIFdlIHJlcGxpY2F0ZWQgdGhlIGNyb3NzZXMgMTIgdGltZXMgdG8gc3VwcGx5IHRoZSBmbGllcyB1c2VkIGluIGdlbmVyYXRpb24gemVybyBvZiBleHBlcmltZW50YWwgZXZvbHV0aW9uOyA2IHRpbWVzIHVzaW5nIHRoZSBfVWJpXyBHRlAgY29uc3RydWN0IGFuZCA2IHRpbWVzIHdpdGggdGhlIF8zeFBfIGNvbnN0cnVjdC4gRyA9IGdlbmVyYXRpb24uCgokfiQKCiMgQW5hbHlzaXMKCiR+JAoKIyMgTW9ydGFsaXR5IGFuYWx5c2lzCgokfiQKCldlIGNvbmR1Y3RlZCBzaW5nbGUtcGFpciBmdWxsLXNpYmxpbmcgY3Jvc3NlcyB0byBlcm9kZSBoZXRlcm96eWdvc2l0eSBhY3Jvc3MgdGhlIGdlbm9tZSwgdGhlcmVieSBleHBvc2luZyBtdXRhdGlvbiBsb2FkLiBPdXIgcHJveGllcyBmb3IgbXV0YXRpb24gbG9hZCAtIGV4dGluY3Rpb24gcmF0ZSBhbmQgcHJvZHVjdGl2aXR5IGRlY2xpbmUgLSBtYXkgYWxzbyBoYXZlIGJlZW4gYWZmZWN0ZWQgYnkgZGlmZmVyZW5jZXMgaW4gdGhlIGludGVuc2l0eSBvZiBpbnRlcmxvY3VzIHNleHVhbCBjb25mbGljdCBiZXR3ZWVuIHN1YnBvcHVsYXRpb25zIGNhcnJ5aW5nIGF1dG9zb21lcyB3aXRoIGRpZmZlcmVudCBzZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yaWVzLiAqKldlIHNwZWNpZmljYWxseSBkZXNpZ25lZCBvdXIgZXhwZXJpbWVudCB0byBtaW5pbWlzZSB0aGlzIGVmZmVjdCoqLCBieSBlbmZvcmNpbmcgbW9ub2dhbXkgYmV0d2VlbiBhbGwgYnJlZWRpbmcgaW5kaXZpZHVhbHMgYWNyb3NzIHRoZSBleHRpbmN0aW9uIGFzc2F5LiBIb3dldmVyLCB3ZSBjYW5ub3QgZGlzY291bnQgbWFsZXMgY2FycnlpbmcgbWFsZS1saW1pdGVkIGF1dG9zb21lcyBhbmQvIG9yIGNvbnRyb2wgYXV0b3NvbWVzIGJlaW5nIG1vcmUgaGFybWZ1bCB0byBmZW1hbGVzIHRoYW4gbWFsZXMgY2FycnlpbmcgYXV0b3NvbWVzIHdpdGggYSBmZW1hbGUtbGltaXRlZCBzZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yeS4gVGhpcyBtaWdodCBvY2N1ciBiZWNhdXNlIG1hbGUgaGFybSBpcyBhIGJ5LXByb2R1Y3Qgb2YgbWFsZS1tYWxlIGNvbXBldGl0aW9uLCB3aGljaCBjYW5ub3QgcmVzcG9uZCB0byBzZWxlY3Rpb24gaW4gdGhlIGZlbWFsZS1saW1pdGVkIHRyZWF0bWVudHMuIEZ1cnRoZXJtb3JlLCB0cmFpdHMgZ2VuZXRpY2FsbHkgY29ycmVsYXRlZCB3aXRoIGhhcm0gc3VjaCBhcyBhY3Rpdml0eSBsZXZlbHMgb3IgbWV0YWJvbGljIHJhdGUgbWF5IGJlIHNlbGVjdGVkIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24gYW1vbmcgZmVtYWxlcywgYXMgdGhlc2UgdHJhaXRzIGFyZSBoaWdobHkgc2V4dWFsbHkgZGltb3JwaGljLiBUaGlzIG1heSBkcml2ZSB0aGUgZXZvbHV0aW9uIG9mIHJlZHVjZWQgaGFybSBkdXJpbmcgZmVtYWxlLWxpbWl0ZWQgZXZvbHV0aW9uLiAKCldlIG9ic2VydmUgMTM1IGZlbWFsZSAoNi4yJSkgYW5kIDIxICgxJSkgbWFsZSBtb3J0YWxpdGllcyBhY3Jvc3MgdGhlIDIxODQgX0Ryb3NvcGhpbGFfIHZpYWxzIHVzZWQgZHVyaW5nIHRoZSAyMCBnZW5lcmF0aW9ucyBvZiB0aGUgZXhwZXJpbWVudCAod2UgZG8gbm90IGluY2x1ZGUgdGhlIDkgZmluYWwgZ2VuZXJhdGlvbnMgb2JzZXJ2ZWQgaW4gQmxvY2sgMSBpbiB0aGlzIGFuYWx5c2lzKS4gTWFsZSBtb3J0YWxpdHkgZGlkIG5vdCBvY2N1ciBvZnRlbiBlbm91Z2ggdG8gcHJvdmlkZSB0aGUgcG93ZXIgcmVxdWlyZWQgZm9yIGZvcm1hbCBhbmFseXNpcy4gV2UgaW5zdGVhZCBmb2N1cyBvbiBtb2RlbGxpbmcgZmVtYWxlIG1vcnRhbGl0eSBhbmQgdGVzdCB3aGV0aGVyIHRoaXMgaXMgYWZmZWN0ZWQgYnkgc2VsZWN0aW9uIHJlc3BvbnNlIGhpc3RvcnkuIAoKV2UgdGVzdCB0aGlzIGh5cG90aGVzaXMgdG8gYXNzZXNzIHdoZXRoZXIgaXQgaXMgcmVxdWlyZWQgdG8gY2Vuc29yIHN1YnBvcHVsYXRpb25zIHdoZXJlIHRoZSBicmVlZGluZyBmZW1hbGUgZGllZCBpbiB0aGUgZ2VuZXJhdGlvbiBvZiBleHRpbmN0aW9uLgoKJH4kCgojIyMgTG9hZCBpbiB0aGUgZGF0YQoKYGBge3J9Cgptb3J0YWxpdHlfZGF0YSA8LSAKICByZWFkX2NzdigiRGF0YS9Nb3J0YWxpdHlfZGF0YS5jc3YiKSAlPiUgCiAgcm93aWRfdG9fY29sdW1uKCJzdWJwb3B1bGF0aW9uIikgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gODoyNywgbmFtZXNfdG8gPSAiR2VuZXJhdGlvbiIsIHZhbHVlc190byA9ICJGZW1hbGVfbW9ydGFsaXR5IikgJT4lIAogIG11dGF0ZSgKICAgIEdlbmVyYXRpb24gPSBhcy5pbnRlZ2VyKHN0cl9yZW1vdmUoR2VuZXJhdGlvbiwgIkdlbl8iKSksCiAgICBXZWVrID0gY2FzZV93aGVuKAogICAgQmxvY2sgPT0gMSB+IEdlbmVyYXRpb24sCiAgICBCbG9jayA9PSAyIH4gYXMuaW50ZWdlcihHZW5lcmF0aW9uICsgOSkpLAogICAgV2VlayA9IGFzLmZhY3RvcihXZWVrKSwKICAgIGFjcm9zcygxOjcsIGFzLmZhY3RvciksCiAgICBNYWxlX21vcnRhbGl0eSA9IEZlbWFsZV9tb3J0YWxpdHksCiAgICBGZW1hbGVfbW9ydGFsaXR5ID0gaWZfZWxzZShGZW1hbGVfbW9ydGFsaXR5ID09ICJGRU1BTEUiIHwgRmVtYWxlX21vcnRhbGl0eSA9PSAiQk9USCIsIDEsIDApLAogICAgTWFsZV9tb3J0YWxpdHkgPSBpZl9lbHNlKE1hbGVfbW9ydGFsaXR5ID09ICJNQUxFIiB8IE1hbGVfbW9ydGFsaXR5ID09ICJCT1RIIiwgMSwgMCkpICU+JSAKICByZW5hbWUoRXZvbHV0aW9uX3RyZWF0bWVudCA9IFRyZWF0bWVudCkKCgojIENyZWF0ZSBhIGZ1bmN0aW9uIHRvIGJ1aWxkIEhUTUwgc2VhcmNoYWJsZSB0YWJsZXMKCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpewogIGRhdGF0YWJsZSgKICAgIGRmLCByb3duYW1lcz1GQUxTRSwKICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsCiAgICBleHRlbnNpb25zID0gYygiU2Nyb2xsZXIiLCAgIkJ1dHRvbnMiKSwKICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICBkb20gPSAnQmZydGlwJywKICAgICAgZGVmZXJSZW5kZXI9VFJVRSwKICAgICAgc2Nyb2xsWD1UUlVFLCBzY3JvbGxZPTQwMCwKICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwKICAgICAgYnV0dG9ucyA9CiAgICAgICAgbGlzdCgncGFnZUxlbmd0aCcsICdjb2x2aXMnLCAnY3N2JywgbGlzdCgKICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLAogICAgICAgICAgcGFnZVNpemUgPSAnQTQnLAogICAgICAgICAgb3JpZW50YXRpb24gPSAnbGFuZHNjYXBlJywKICAgICAgICAgIGZpbGVuYW1lID0gJ21vcnRhbGl0eV9kYXRhJykpLAogICAgICBwYWdlTGVuZ3RoID0gODUwMAogICAgKQogICkKfQoKbXlfZGF0YV90YWJsZShtb3J0YWxpdHlfZGF0YSAlPiUgCiAgICAgICAgICAgICAgICBzZWxlY3QoTW90aGVyX3N0cmFpbiwgRmF0aGVyX3N0cmFpbiwgQ3Jvc3MsIHN1YnBvcHVsYXRpb24sIEJsb2NrLCBXZWVrLCBHZW5lcmF0aW9uLCBFdm9sdXRpb25fdHJlYXRtZW50LCBGZW1hbGVfbW9ydGFsaXR5LCBNYWxlX21vcnRhbGl0eSkpCgpgYGAKCiR+JAoKKipDb2x1bW4gZXhwbGFuYXRpb25zKioKCmBNb3RoZXIgc3RyYWluYDogd2UgbWVhc3VyZWQgZXh0aW5jdGlvbiBhbmQgcHJvZHVjdGl2aXR5IG9mIGZhbWlsaWVzIGRlcml2ZWQgZnJvbSAzNiBkaWZmZXJlbnQgY3Jvc3Nlcy4gQ3Jvc3NlcyB3ZXJlIG9ubHkgY29uZHVjdGVkIGJldHdlZW4gc3RyYWlucyB0aGF0IGV4cGVyaWVuY2VkIHRoZSBzYW1lIGBFdm9sdXRpb25fdHJlYXRtZW50YC4gVGhpcyBjb2x1bW4gc2hvd3MgdGhlIHN0cmFpbiB0aGF0IHRoZSBmb3VuZGluZyBmZW1hbGUgb2YgdGhlIHN1YnBvcHVsYXRpb24gd2FzIGRlcml2ZWQgZnJvbS4KCmBGYXRoZXIgc3RyYWluYDogd2UgbWVhc3VyZWQgZXh0aW5jdGlvbiBhbmQgcHJvZHVjdGl2aXR5IG9mIGZhbWlsaWVzIGRlcml2ZWQgZnJvbSAzNiBkaWZmZXJlbnQgY3Jvc3Nlcy4gQ3Jvc3NlcyB3ZXJlIG9ubHkgY29uZHVjdGVkIGJldHdlZW4gc3RyYWlucyB0aGF0IGV4cGVyaWVuY2VkIHRoZSBzYW1lIGV2b2x1dGlvbiB0cmVhdG1lbnQuIFRoaXMgY29sdW1uIHNob3dzIHRoZSBzdHJhaW4gdGhhdCB0aGUgZm91bmRpbmcgbWFsZSBvZiB0aGUgc3VicG9wdWxhdGlvbiB3YXMgZGVyaXZlZCBmcm9tLgoKYENyb3NzYDogYW4gaWRlbnRpZnlpbmcgSUQgZm9yIGVhY2ggb2YgdGhlIDM2IGNvbWJpbmF0aW9ucyBvZiBgTW90aGVyIHN0cmFpbmAgYW5kIGBGYXRoZXIgc3RyYWluYC4gCgpgc3VicG9wdWxhdGlvbmA6IGxpbmVzIG9mIGZsaWVzIGZvdW5kZWQgYnkgc2luZ2xlIGluc2VtaW5hdGVkIGZlbWFsZXMgaW4gZ2VuZXJhdGlvbiB6ZXJvLiBXZSBnZW5lcmF0ZWQgdGhlIG5leHQgZ2VuZXJhdGlvbiBvZiBlYWNoIHN1YnBvcHVsYXRpb24gYnkgY3Jvc3NpbmcgYSBzaW5nbGUgZnVsbC1zaWJsaW5nIGR5YWQuCgpgQmxvY2tgOiB0aGUgZXhwZXJpbWVudCB3YXMgcnVuIGluIDIgZGlzdGluY3QgYmxvY2tzLCB1c2luZyBmbGllcyBzZXBhcmF0ZWQgYnkgOSBnZW5lcmF0aW9ucy4KCmBXZWVrYDogdGhlIHdlZWsgdGhhdCB0aGUgZ2VuZXJhdGlvbiBvZiBlYWNoIGJsb2NrIHdhcyBjb25kdWN0ZWQgaW4uIExhYm9yYXRvcnkgY29uZGl0aW9ucyBtYXkgaGF2ZSBkaWZmZXJlZCBzbGlnaHRseSBiZXR3ZWVuIHdlZWtzLiBGb3IgZXhhbXBsZSwgYSBuZXcgYmF0Y2ggb2YgZm9vZCB3YXMgY29va2VkIGZvciBlYWNoIHdlZWsuIE5vdGUgdGhhdCBibG9ja3Mgb3ZlcmxhcCBiZXR3ZWVuIHdlZWtzIDktMjAuCgpgR2VuZXJhdGlvbmA6IHRoZSBnZW5lcmF0aW9uIG9mIHRoZSBleHRpbmN0aW9uIGFzc2F5LCByYW5naW5nIGZyb20gMSB0byAyMC4gCgpgRXZvbHV0aW9uX3RyZWF0bWVudGA6IHRoZSBzdHJhaW5zIGhhZCBiZWVuIGV4cG9zZWQgdG8gb25lIG9mIHRocmVlIGV2b2x1dGlvbmFyeSBjb25kaXRpb25zIGZvciAyMCBnZW5lcmF0aW9uczogYSBmZW1hbGUtbGltaXRlZCByZXNwb25zZSB0byBzZWxlY3Rpb24sIGEgbWFsZS1saW1pdGVkIHJlc3BvbnNlIGFuZCBhIGNvbnRyb2wgY29uZGl0aW9uIHdoZXJlIGFuIGV2b2x1dGlvbmFyeSByZXNwb25zZSBvY2N1cnJlZCBpbiBib3RoIHNleGVzLgoKYEZlbWFsZV9tb3J0YWxpdHlgOiBhIDAgaW5kaWNhdGVzIHRoZSBmZW1hbGUgc3Vydml2ZWQgdW50aWwgc2hlIHdhcyByZW1vdmVkIGZyb20gdGhlIDMtZGF5IGJyZWVkaW5nIHZpYWwuIEEgMSBpbmRpY2F0ZXMgc2hlIGRpZWQgZHVyaW5nIHRoaXMgcGVyaW9kLiBGZW1hbGVzIHdlcmUgMS00IGRheXMgb2xkIHdoZW4gdGhleSBlbnRlcmVkIHRoZSBicmVlZGluZyB2aWFsLgoKYE1hbGVfbW9ydGFsaXR5YDogc2VlIGBGZW1hbGVfbW9ydGFsaXR5YCwgZXhjZXB0IHRoaXMgY29sdW1uIGRvY3VtZW50cyBtYWxlIG1vcnRhbGl0eSBpbiB0aGUgYnJlZWRpbmcgdmlhbHMuCgokfiQKCiMjIyBNb2RlbGxpbmcgYXBwcm9hY2gKCiR+JAoKV2UgZml0IGEgYmlub21pYWwgbW9kZWwgd2l0aCBgRmVtYWxlX21vcnRhbGl0eWAgYXMgdGhlIHJlc3BvbnNlLCBgRXZvbHV0aW9uX3RyZWF0bWVudGAgYXMgYSBmaXhlZCBlZmZlY3QgYW5kIGBXZWVrYCwgYHN1YnBvcHVsYXRpb25gIGFuZCBgQ3Jvc3NgIGFzIHJhbmRvbSBlZmZlY3RzLgoKKipQcmlvcnMqKgoKV2UgZml0IG1vZGVyYXRlbHkgaW5mb3JtYXRpdmUgcHJpb3JzLCB3aXRoIHRoZSBhaW0gdG8gcmVndWxhcmlzZSBvdXIgcG9zdGVyaW9yIGVzdGltYXRlcyBhbmQgaW1wcm92ZSBtb2RlbCBmaXR0aW5nIGJ5IHJ1bGluZyBvdXQgbm9uLXNlbnNpY2FsIHZhbHVlcy4KCk5vdGUgdGhhdCBlYWNoIG9mIHRoZXNlIHByaW9ycyBpcyBleHByZXNzZWQgb24gdGhlIGxvZ2l0IHNjYWxlLCBkdWUgdG8gdGhlIGJpbm9taWFsIGxvZ2l0IGxpbmsuCgokXGFscGhhJCAodGhlIGludGVyY2VwdHMpIH4gTm9ybWFsKCRcbXUkID0gLTIsICRcc2lnbWEkID0gMikKCiRcYmV0YSQgKHRoZSBmaXhlZCBlZmZlY3RzKSB+IE5vcm1hbCgkXG11JCA9IDAsICRcc2lnbWEkID0gMikgCgokXHNpZ21hJCB+IEV4cG9uZW50aWFsKHJhdGUgPSAxKQoKCmBgYHtyfQpmZW1hbGVfbW9ydGFsaXR5X21vZGVsIDwtIAogIGJybShGZW1hbGVfbW9ydGFsaXR5IH4gMSArIEV2b2x1dGlvbl90cmVhdG1lbnQgKyAoMXxXZWVrKSArICgxfENyb3NzKSArICgxfHN1YnBvcHVsYXRpb24pLAogICAgICBkYXRhID0gbW9ydGFsaXR5X2RhdGEgJT4lIGZpbHRlcihGZW1hbGVfbW9ydGFsaXR5ICE9ICJOQSIpLAogICAgICBmYW1pbHkgPSBiZXJub3VsbGksCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoLTIsIDIpLCBjbGFzcyA9IEludGVyY2VwdCksCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoMCwgMiksIGNsYXNzID0gYiksCiAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCkpLAogICAgICBpdGVyID0gODAwMCwgd2FybXVwID0gNDAwMCwgY2hhaW5zID0gNCwgY29yZXMgPSA0LCBzZWVkID0gMSwKICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjk4KSwKICAgICAgZmlsZSA9ICJGaXRzL2ZlbWFsZV9tb3J0YWxpdHlfbW9kZWwiKQpgYGAKCgojIyMgRXh0cmFjdCBtb2RlbCBwcmVkaWN0aW9ucyBhbmQgcGxvdAoKYGBge3J9Cgptb3J0YWxpdHlfcHJlZGljdGlvbnMgPC0KICBmZW1hbGVfbW9ydGFsaXR5X21vZGVsICU+JSAKICBhc19kcmF3c19kZigpICU+JSAKICBtdXRhdGUoQ29udHJvbCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQpKjEwMCwKICAgICAgICAgYEZlbWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUpKjEwMCwKICAgICAgICAgYE1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50TWFsZSkqMTAwKSAlPiUgCiAgc2VsZWN0KENvbnRyb2wsIGBGZW1hbGUtbGltaXRlZGAsIGBNYWxlLWxpbWl0ZWRgKQogICAgCiMgcHV0IGluIGVhc3kgdG8gcGxvdCBmb3JtYXQKCm1vcnRhbGl0eV9wcmVkaWN0aW9uc19sb25nIDwtCiAgbW9ydGFsaXR5X3ByZWRpY3Rpb25zICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGV2ZXJ5dGhpbmcoKSwgbmFtZXNfdG8gPSAiRXZvbHV0aW9uX3RyZWF0bWVudCIsIHZhbHVlc190byA9ICJNb3J0YWxpdHkiKQoKIyBjYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gZWFjaCB0cmVhdG1lbnQKCm1vcnRhbGl0eV9kaWZmIDwtCiAgbW9ydGFsaXR5X3ByZWRpY3Rpb25zICU+JSAKICBtdXRhdGUoYENvbnRyb2wgLSBNYWxlLWxpbWl0ZWRgID0gQ29udHJvbCAtIGBNYWxlLWxpbWl0ZWRgLAogICAgICAgICBgTWFsZS1saW1pdGVkIC0gRmVtYWxlLWxpbWl0ZWRgID0gYE1hbGUtbGltaXRlZGAgLSBgRmVtYWxlLWxpbWl0ZWRgLAogICAgICAgICBgQ29udHJvbCAtIEZlbWFsZS1saW1pdGVkYCA9IENvbnRyb2wgLSBgRmVtYWxlLWxpbWl0ZWRgKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSA0OjYsIG5hbWVzX3RvID0gIkRpZmZlcmVuY2VfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAiRGlmZmVyZW5jZSIpICU+JSAKICBzZWxlY3QoY29udGFpbnMoIkRpZmYiKSkKCmBgYAoKIyMjIEJ1aWxkIEZpZ3VyZSBTMgoKYGBge3J9Cm1vcnRhbGl0eV9wbG90IDwtCiAgbW9ydGFsaXR5X3ByZWRpY3Rpb25zX2xvbmcgJT4lIAogIGdncGxvdChhZXMoeCA9IE1vcnRhbGl0eSwgeSA9IEV2b2x1dGlvbl90cmVhdG1lbnQpKSArCiAgICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBFdm9sdXRpb25fdHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwgCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGxhYnMoeD0gIkZlbWFsZSBtb3J0YWxpdHkgKCUpIiwgeSA9ICJJbmhlcml0YW5jZSB0cmVhdG1lbnQiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKbW9ydGFsaXR5X2RpZmZfcGxvdCA8LSAKICBtb3J0YWxpdHlfZGlmZiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gRGlmZmVyZW5jZSwgeSA9IGZjdF9yZWxldmVsKERpZmZlcmVuY2VfY29udHJhc3QsICJDb250cm9sIC0gRmVtYWxlLWxpbWl0ZWQiLCAiTWFsZS1saW1pdGVkIC0gRmVtYWxlLWxpbWl0ZWQiLCAiQ29udHJvbCAtIE1hbGUtbGltaXRlZCIpKSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IERpZmZlcmVuY2VfY29udHJhc3QpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lZGlhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41KSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoY2FydG9fcGFsKDcsICJQZWFjaCIpWzJdLCBjYXJ0b19wYWwoNywgIlB1cnAiKVsxXSwgY2FydG9fcGFsKDcsICJUZWFsR3JuIilbMV0pKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAxKSArCiAgbGFicyh4ID0gIkRpZmYuIGluIG1vcnRhbGl0eSAoJSBwb2ludHMpIiwgeSA9ICJUcmVhdG1lbnQgY29udHJhc3QiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoLTIsIDYsIDIpLCBsaW1pdHMgPSBjKC0zLCA3KSkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvcj1OQSksICN0cmFuc3BhcmVudCBwbG90IGJnCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAjdHJhbnNwYXJlbnQgbGVnZW5kIHBhbmVsCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCiAgbW9ydGFsaXR5X3Bsb3QgLyBtb3J0YWxpdHlfZGlmZl9wbG90ICsKICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICdhJykKCmBgYAoKKipGaWd1cmUgUzIqKi4gRmVtYWxlIG1vcnRhbGl0eSBpcyBsZXNzIGZyZXF1ZW50IGluIHN1YnBvcHVsYXRpb25zIHdpdGggZmVtYWxlLWxpbWl0ZWQgc2VsZWN0aW9uIHJlc3BvbnNlIGhpc3Rvcmllcywgc3VnZ2VzdGluZyB0aGF0IG1hbGUgaGFybSBtYXkgYmUgbGVzcyBpbnRlbnNlIGluIHRoZXNlIHN1YnBvcHVsYXRpb25zLiBQYW5lbCAqKmEqKiBzaG93cyB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBvZiB0aGUgbWVhbiBwZXJjZW50YWdlIG9mIGZlbWFsZSBtb3J0YWxpdHkgZXZlbnRzIGFjcm9zcyB0aGUgdG90YWwgbnVtYmVyIG9mIHZpYWxzIHRoYXQgaG91c2VkIHN1YnBvcHVsYXRpb25zIHRocm91Z2hvdXQgdGhlIGV4dGluY3Rpb24gYXNzYXksIHNwbGl0IGJ5IHNlbGVjdGlvbiByZXNwb25zZSBoaXN0b3J5LiBQYW5lbCAqKmIqKiBzaG93cyB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGVhY2ggdHJlYXRtZW50LiBUaGUgcG9pbnRzIHNob3cgdGhlIGVzdGltYXRlZCBtZWRpYW4sIHdpdGggYXNzb2NpYXRlZCA2NiBhbmQgOTUlIGNyZWRpYmxlIGludGVydmFscy4gCgokfiQKClRvIGF2b2lkIHRoaXMgY29uZm91bmRpbmcgb3VyIG1lYXN1cmUgb2YgbXV0YXRpb24gbG9hZCwgd2UgY2FuIGNlbnNvciBleHRpbmN0aW9uIGV2ZW50cyB0aGF0IGNvLW9jY3VyIHdpdGggZmVtYWxlIG1vcnRhbGl0eS4KCiR+JAoKIyMgRXh0aW5jdGlvbiBhbmFseXNpcwoKIyMjIExvYWQgaW4gdGhlIGV4dGluY3Rpb24gZGF0YSAKCiR+JAoKYGBge3J9CgpleHRpbmN0aW9uX2RhdGEgPC0gCiAgcmVhZF9jc3YoIkRhdGEvRXh0aW5jdGlvbl9kYXRhLmNzdiIpIAoKIyBCbG9jayAxIHJ1bnMgZm9yIDI5IGdlbmVyYXRpb25zLCB3aGlsZSBCbG9jayAyIG9ubHkgcnVucyBmb3IgMjAuIFRvIGNhbGN1bGF0ZSB0aGUgY2Vuc29yaW5nIHZhcmlhYmxlLCB3ZSBuZWVkIHRvIHNwbGl0IHRoZXNlIGJ5IEJsb2NrLCBtdXRhdGUgdGhlIGRhdGEsIHRoZW4gcmViaW5kIHRoZW0gCgpCbG9ja18xIDwtCiAgZXh0aW5jdGlvbl9kYXRhICU+JSAKICBmaWx0ZXIoQmxvY2sgPT0gIjEiKSAlPiUgCiAgIyBoZXJlIHdlIGNyZWF0ZSBhIGNlbnNvcmluZyBjb2x1bW4uIElmIHRoZSBmYW1pbHkgYSkgZXNjYXBlZCBvciB3YXMga2lsbGVkIGJ5IHNvbWV0aGluZyB1bnJlbGF0ZWQgdG8gdGhlIGV4cGVyaW1lbnQgb3IgYikgc3Vydml2ZWQgdGhlIDIwIGdlbmVyYXRpb25zIG9mIHRoZSBleHBlcmltZW50LCB0aGVuIHdlIGNvZGUgYSB2YWx1ZSBvZiAxLiBJZiB0aGUgZmFtaWx5IHdlbnQgZXh0aW5jdCwgd2UgY29kZSBhIHZhbHVlIG9mIDAuIFRoaXMgYWxsb3dzIHVzIHRvIHJpZ2h0IGNlbnNvciB0aGUgZGF0YSwgdGhlcmVieSBwcmVzZXJ2aW5nIHRoZSBpbmZvcm1hdGlvbiBpdCBwcm92aWRlcyBvbiBleHRpbmN0aW9uLgogIG11dGF0ZShhY3Jvc3MoR2VuXzE6R2VuXzI5LCB+cmVwbGFjZV9uYSgueCwgIkVzY2FwZSIpKSwKICAgICAgICAgQ2Vuc29yZWRfYWxpdmUgPSBpZl9lbHNlKEdlbl8yOSA9PSAiWUVTIiwgMSwgMCksCiAgICAgICAgIENlbnNvcmVkX2VzY2FwZSA9IGlmX2Vsc2UoR2VuXzI5ID09ICJFc2NhcGUiLCAxLCAwKSwKICAgICAgICAgQ2Vuc29yZWQgPSBDZW5zb3JlZF9hbGl2ZSArIENlbnNvcmVkX2VzY2FwZSwKICAgICAgICAgYWNyb3NzKEdlbl8xOkdlbl8yOSwgfmlmX2Vsc2UoLnggPT0gIllFUyIsIDEsIDApKSkKICAgICAgICAKCkJsb2NrXzIgPC0KICBleHRpbmN0aW9uX2RhdGEgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiMiIpICU+JSAKICAjIGhlcmUgd2UgY3JlYXRlIGEgY2Vuc29yaW5nIGNvbHVtbi4gSWYgdGhlIGZhbWlseSBhKSBlc2NhcGVkIG9yIHdhcyBraWxsZWQgYnkgc29tZXRoaW5nIHVucmVsYXRlZCB0byB0aGUgZXhwZXJpbWVudCBvciBiKSBzdXJ2aXZlZCB0aGUgMjAgZ2VuZXJhdGlvbnMgb2YgdGhlIGV4cGVyaW1lbnQsIHRoZW4gd2UgY29kZSBhIHZhbHVlIG9mIDEuIElmIHRoZSBmYW1pbHkgd2VudCBleHRpbmN0LCB3ZSBjb2RlIGEgdmFsdWUgb2YgMC4gVGhpcyBhbGxvd3MgdXMgdG8gcmlnaHQgY2Vuc29yIHRoZSBkYXRhLCB0aGVyZWJ5IHByZXNlcnZpbmcgdGhlIGluZm9ybWF0aW9uIGl0IHByb3ZpZGVzIG9uIGV4dGluY3Rpb24uCiAgbXV0YXRlKGFjcm9zcyhHZW5fMTpHZW5fMjAsIH5yZXBsYWNlX25hKC54LCAiRXNjYXBlIikpLAogICAgICAgICBhY3Jvc3MoR2VuXzIxOkdlbl8yOSwgfnJlcGxhY2VfbmEoLngsICJOb3QgbWVhc3VyZWQiKSksCiAgICAgICAgIENlbnNvcmVkX2FsaXZlID0gaWZfZWxzZShHZW5fMjAgPT0gIllFUyIsIDEsIDApLAogICAgICAgICBDZW5zb3JlZF9lc2NhcGUgPSBpZl9lbHNlKEdlbl8yMCA9PSAiRXNjYXBlIiwgMSwgMCksCiAgICAgICAgIENlbnNvcmVkID0gQ2Vuc29yZWRfYWxpdmUgKyBDZW5zb3JlZF9lc2NhcGUsCiAgICAgICAgIGFjcm9zcyhHZW5fMTpHZW5fMjksIH5pZl9lbHNlKC54ID09ICJZRVMiLCAxLCAwKSkpCgojIGNvbWJpbmUgdGhlIEJsb2NrZWQgZGF0YSBiYWNrIGludG8gYSBzaW5nbGUgdGliYmxlCgpleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQgPC0KICByYmluZChCbG9ja18xLCBCbG9ja18yKSAlPiUKICBtdXRhdGUoYWNyb3NzKDE6NywgYXMuZmFjdG9yKSwgCiAgICAgICAgIEdlbnNfdG9fZXh0aW5jdCA9IEdlbl8xICsgR2VuXzIgKyBHZW5fMyArIEdlbl80ICsgCiAgICAgICAgICAgR2VuXzUgKyBHZW5fNiArIEdlbl83ICsgR2VuXzggKyBHZW5fOSArIEdlbl8xMCArIAogICAgICAgICAgIEdlbl8xMSArIEdlbl8xMiArIEdlbl8xMyArIEdlbl8xNCArIEdlbl8xNSArIEdlbl8xNiArIAogICAgICAgICAgIEdlbl8xNyArIEdlbl8xOCArIEdlbl8xOSArIEdlbl8yMCArIEdlbl8yMSArIEdlbl8yMiArIAogICAgICAgICAgIEdlbl8yMyArIEdlbl8yNCArIEdlbl8yNSArIEdlbl8yNiArIEdlbl8yNyArIEdlbl8yOCArIEdlbl8yOSArIDEpICU+JSAKICByZW5hbWUoRXZvbHV0aW9uX3RyZWF0bWVudCA9IFRyZWF0bWVudCwgc3VicG9wdWxhdGlvbiAgPSBJRCkgJT4lIAogIHNlbGVjdChNb3RoZXJfc3RyYWluLCBGYXRoZXJfc3RyYWluLCBDcm9zcywgc3VicG9wdWxhdGlvbiwgQmxvY2ssIAogICAgICAgICBFdm9sdXRpb25fdHJlYXRtZW50LCBHZW5zX3RvX2V4dGluY3QsIEdlbl8xOkdlbl8yOSwgQ2Vuc29yZWRfYWxpdmUsIAogICAgICAgICBDZW5zb3JlZF9lc2NhcGUsIENlbnNvcmVkKQoKIyBGaW5kIHRoZSBleHRpbmN0aW9ucyB0aGF0IGNvLW9jY3VyIHdpdGggZmVtYWxlIG1vcnRhbGl0eQoKZXh0aW5jdGlvbl9tb3J0YWxpdHkgPC0KICBsZWZ0X2pvaW4oCiAgICBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQgJT4lIAogICAgICBwaXZvdF9sb25nZXIoY29scyA9IDg6MzYsIG5hbWVzX3RvID0gIkdlbmVyYXRpb24iLCB2YWx1ZXNfdG8gPSAiRXh0YW50IikgJT4lIAogICAgICBtdXRhdGUoR2VuZXJhdGlvbiA9IGFzLmludGVnZXIoc3RyX3JlbW92ZShHZW5lcmF0aW9uLCAiR2VuXyIpKSksCiAgICAKICAgIG1vcnRhbGl0eV9kYXRhCiAgKSAlPiUgCiAgZmlsdGVyKEV4dGFudCA9PSAwICYgRmVtYWxlX21vcnRhbGl0eSA9PSAxKSAlPiUgCiAgbXV0YXRlKENlbnNvcmVkX21vcnRhbGl0eSA9IDEpICU+JSAKICBzZWxlY3Qoc3VicG9wdWxhdGlvbiwgQ2Vuc29yZWRfbW9ydGFsaXR5KQoKZXh0aW5jdGlvbl9kYXRhX3dyYW5nbGVkIDwtIGxlZnRfam9pbihleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQsIGV4dGluY3Rpb25fbW9ydGFsaXR5KSAlPiUgCiAgbXV0YXRlKENlbnNvcmVkX21vcnRhbGl0eSA9IGlmX2Vsc2UoaXMubmEoQ2Vuc29yZWRfbW9ydGFsaXR5KSwgMCwgMSksCiAgICAgICAgIENlbnNvcmVkXzIgPSBDZW5zb3JlZCArIENlbnNvcmVkX21vcnRhbGl0eSkKCiMgQ3JlYXRlIGEgZnVuY3Rpb24gdG8gYnVpbGQgSFRNTCBzZWFyY2hhYmxlIHRhYmxlcwoKbXlfZGF0YV90YWJsZSA8LSBmdW5jdGlvbihkZil7CiAgZGF0YXRhYmxlKAogICAgZGYsIHJvd25hbWVzPUZBTFNFLAogICAgYXV0b0hpZGVOYXZpZ2F0aW9uID0gVFJVRSwKICAgIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICAiQnV0dG9ucyIpLAogICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICBkZWZlclJlbmRlcj1UUlVFLAogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLAogICAgICBzY3JvbGxDb2xsYXBzZT1UUlVFLAogICAgICBidXR0b25zID0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KAogICAgICAgICAgZXh0ZW5kID0gJ3BkZicsCiAgICAgICAgICBwYWdlU2l6ZSA9ICdBNCcsCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLAogICAgICAgICAgZmlsZW5hbWUgPSAnZXh0aW5jdGlvbl9kYXRhJykpLAogICAgICBwYWdlTGVuZ3RoID0gNTAwCiAgICApCiAgKQp9CgpteV9kYXRhX3RhYmxlKGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCkKYGBgCgoqKkNvbHVtbiBleHBsYW5hdGlvbnMqKgoKYE1vdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgYEV2b2x1dGlvbl90cmVhdG1lbnRgLiBUaGlzIGNvbHVtbiBzaG93cyB0aGUgc3RyYWluIHRoYXQgdGhlIGZvdW5kaW5nIGZlbWFsZSBvZiB0aGUgc3VicG9wdWxhdGlvbiB3YXMgZGVyaXZlZCBmcm9tLgoKYEZhdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgZXZvbHV0aW9uIHRyZWF0bWVudC4gVGhpcyBjb2x1bW4gc2hvd3MgdGhlIHN0cmFpbiB0aGF0IHRoZSBmb3VuZGluZyBtYWxlIG9mIHRoZSBzdWJwb3B1bGF0aW9uIHdhcyBkZXJpdmVkIGZyb20uCgpgQ3Jvc3NgOiBhbiBpZGVudGlmeWluZyBJRCBmb3IgZWFjaCBvZiB0aGUgMzYgY29tYmluYXRpb25zIG9mIGBNb3RoZXIgc3RyYWluYCBhbmQgYEZhdGhlciBzdHJhaW5gLiAKCmBzdWJwb3B1bGF0aW9uYDogbGluZXMgb2YgZmxpZXMgZm91bmRlZCBieSBzaW5nbGUgaW5zZW1pbmF0ZWQgZmVtYWxlcyBpbiBnZW5lcmF0aW9uIHplcm8uIFdlIGdlbmVyYXRlZCB0aGUgbmV4dCBnZW5lcmF0aW9uIG9mIGVhY2ggc3VicG9wdWxhdGlvbiBieSBjcm9zc2luZyBhIHNpbmdsZSBmdWxsLXNpYmxpbmcgZHlhZC4KCmBCbG9ja2A6IHRoZSBleHBlcmltZW50IHdhcyBydW4gaW4gMiBkaXN0aW5jdCBibG9ja3MsIHVzaW5nIGZsaWVzIHNlcGFyYXRlZCBieSA5IGdlbmVyYXRpb25zLiBCbG9jayAxIHJhbiBmb3IgMjkgZ2VuZXJhdGlvbnMsIHdoZXJlYXMgQmxvY2sgMiByYW4gZm9yIDIwIGdlbmVyYXRpb25zLgoKYEV2b2x1dGlvbl90cmVhdG1lbnRgOiB0aGUgc3RyYWlucyBoYWQgYmVlbiBleHBvc2VkIHRvIG9uZSBvZiB0aHJlZSBldm9sdXRpb25hcnkgY29uZGl0aW9ucyBmb3IgMjAtMjkgZ2VuZXJhdGlvbnM6IGEgZmVtYWxlLWxpbWl0ZWQgcmVzcG9uc2UgdG8gc2VsZWN0aW9uLCBhIG1hbGUtbGltaXRlZCByZXNwb25zZSBhbmQgYSBjb250cm9sIGNvbmRpdGlvbiB3aGVyZSBhbiBldm9sdXRpb25hcnkgcmVzcG9uc2Ugb2NjdXJyZWQgaW4gYm90aCBzZXhlcy4KCmBHZW5zX3RvX2V4dGluY3Rpb25gOiB0aGUgbnVtYmVyIG9mIGdlbmVyYXRpb25zIHRoZSBzdWJwb3B1bGF0aW9uIHN1cnZpdmVkIHVudGlsIGl0IHdlbnQgZXh0aW5jdC4KCmBHZW5fMToyOWA6IGEgMSBpbmRpY2F0ZXMgdGhlIHN1YnBvcHVsYXRpb24gd2FzIGV4dGFudCBmb3IgdGhlIGdlbmVyYXRpb24gaW4gcXVlc3Rpb24sIHdoaWxlIGEgMCBpbmRpY2F0ZXMgZXh0aW5jdGlvbi4gTm90ZSB0aGF0IHdlIGNvbnRpbnVlZCBwcm9wYWdhdGluZyBzdXJ2aXZpbmcgc3VicG9wdWxhdGlvbnMgZnJvbSBCbG9jayAxIHVudGlsIGdlbmVyYXRpb24gMjksIHdoaWNoIGNvaW5jaWRlZCB3aXRoIGdlbmVyYXRpb24gMjAgZm9yIHN1YnBvcHVsYXRpb25zIGJlbG9uZ2luZyB0byB0aGUgc2Vjb25kIEJsb2NrLgoKYENlbnNvcmVkYDogaWYgdGhlIHN1YnBvcHVsYXRpb24gMSkgZW5kZWQgYmVjYXVzZSBmbGllcyBlc2NhcGVkIG9yIHdlcmUga2lsbGVkIGJ5IHNvbWV0aGluZyB1bnJlbGF0ZWQgdG8gdGhlIGV4cGVyaW1lbnQsIDIpIHdlbnQgZXh0aW5jdCBiZWNhdXNlIG9mIGJyZWVkaW5nIGZlbWFsZSBtb3J0YWxpdHkgb3IgMykgd2FzIGV4dGFudCBhZnRlciB0aGUgZmluYWwgZ2VuZXJhdGlvbiBvZiB0aGUgZXhwZXJpbWVudCwgdGhlbiB3ZSBjb2RlZCBhIHZhbHVlIG9mIDEuIElmIHRoZSBzdWJwb3B1bGF0aW9uIHdlbnQgZXh0aW5jdCwgd2UgY29kZWQgYSB2YWx1ZSBvZiAwLiBUaGlzIGFsbG93cyB1cyB0byByaWdodCBjZW5zb3IgdGhlIGRhdGEgYXMgcGVyIHRoZSBgYnJtc2Agc3ludGF4LCB0aGVyZWJ5IHByZXNlcnZpbmcgdGhlIGluZm9ybWF0aW9uIHRoZXNlIGNlbnNvcmVkIGNhc2VzIHByb3ZpZGUgb24gZXh0aW5jdGlvbi4KCiR+JAoKCiMjIyBNb2RlbGxpbmcgYXBwcm9hY2gKCiR+JAoKV2UgZml0IGEgd2VpYnVsbCBzdXJ2aXZhbCBtb2RlbCB0byBlc3RpbWF0ZSBcbGFtYmRhLCB0aGUgZXh0aW5jdGlvbiByYXRlIG9mIHRoZSBzdWJwb3B1bGF0aW9ucyB1c2VkIGluIG91ciBleHBlcmltZW50LiBUaGUgd2VpYnVsbCBtb2RlbCBpcyBhbiBleHRlbnNpb24gb2YgYW4gZXhwb25lbnRpYWwgZGVjYXkgbW9kZWwsIGFuZCBpbmNsdWRlcyBhbiBhZGRpdGlvbmFsIHNoYXBlIHBhcmFtZXRlciwgd2hpY2ggYWxsb3dzIFxsYW1iZGEgdG8gdmFyeSBhY3Jvc3MgZ2VuZXJhdGlvbnMgb2YgaW5icmVlZGluZy4KCldlIHJpZ2h0IGNlbnNvciBzdWJwb3B1bGF0aW9ucyB0aGF0IDEpIGVuZGVkIGJlY2F1c2UgZmxpZXMgZXNjYXBlZCBvciB3ZXJlIGtpbGxlZCBieSBzb21ldGhpbmcgdW5yZWxhdGVkIHRvIHRoZSBleHBlcmltZW50LCAyKSB3ZW50IGV4dGluY3QgYmVjYXVzZSBvZiBicmVlZGluZyBmZW1hbGUgbW9ydGFsaXR5IG9yIDMpIHdlcmUgZXh0YW50IGFmdGVyIHRoZSBmaW5hbCBnZW5lcmF0aW9uIG9mIHRoZSBleHBlcmltZW50CgoqKlJlc3BvbnNlIHZhcmlhYmxlKioKCmBHZW5zX3RvX2V4dGluY3RgIGlzIG91ciByZXNwb25zZSAtIGEgY29udGludW91cyB2YXJpYWJsZSB0aGF0IHJ1bnMgZnJvbSAxIHRvIDMwIGdlbmVyYXRpb25zLiBOb3RlIHRoYXQgd2UgbWVhc3VyZWQgZXh0aW5jdGlvbiB1cCB1bnRpbCBnZW5lcmF0aW9uIDI5IGluIEJsb2NrIDEgYW5kIGdlbmVyYXRpb24gMjAgaW4gQmxvY2sgMi4gQSB2YWx1ZSBvZiAzMCBpbmRpY2F0ZXMgdGhhdCB0aGUgc3VicG9wdWxhdGlvbiB3YXMgZXh0YW50IGF0IHRoZSBlbmQgb2YgdGhlIGV4cGVyaW1lbnQgaW4gQmxvY2sgMSwgd2hpbGUgYSB2YWx1ZSBvZiAyMSBpbmRpY2F0ZXMgdGhpcyBpbiBCbG9jayAyLiBXZSBhbHNvIGluY2x1ZGUgcmlnaHQgY2Vuc29yaW5nLCB0byBhY2NvdW50IGZvciBzdWJwb3B1bGF0aW9ucyBleHRhbnQgYXQgdGhlIGVuZCBvZiB0aGUgZXhwZXJpbWVudCwgb3IgdGhhdCB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgZXhwZXJpbWVudCBieSBhIGhhbmRsaW5nIGVycm9yLiBDZW5zb3JpbmcgZW5hYmxlcyB0aGUgaW5jbHVzaW9uIG9mIHRoaXMgJ2luY29tcGxldGUnIGRhdGEgaW4gdGhlIG1vZGVsLiAKCioqRml4ZWQgZWZmZWN0cyoqCgpgRXZvbHV0aW9uX3RyZWF0bWVudGA6IHdlIGluY2x1ZGUgdGhpcyB0byB0ZXN0IGZvciBhIGNhdXNhbCBlZmZlY3Qgb2Ygc2V4LWxpbWl0ZWQgZXhwZXJpbWVudGFsIGV2b2x1dGlvbiBvbiBtdXRhdGlvbiBsb2FkLiAKCmBCbG9ja2A6IGV4dGluY3Rpb24gcmF0ZSBtaWdodCBkaWZmZXIgYmV0d2VlbiB0aGUgYmxvY2tzIHdlIHNwbGl0IG91ciBleHBlcmltZW50IHVwIGludG8gZS5nLiBiZWNhdXNlIG9mIG1pY3JvdmFyaWF0aW9uIGluIHRoZSBsYWIgYnJvdWdodCBhYm91dCBiZWNhdXNlIG9mIGEgY2hhbmdlIG9mIHNlYXNvbiwgc2xpZ2h0IGluY29uc2lzdGVuY2llcyBpbiBfRHJvc29waGlsYV8gZm9vZCBjb25zaXN0ZW5jeSBldGMuCgoqKlZhcnlpbmcvUmFuZG9tIGVmZmVjdHMqKgoKYENyb3NzYDogd2UgaW5pdGlhdGVkIGVhY2ggc3VicG9wdWxhdGlvbiBieSBjcm9zc2luZyB0d28gc3RyYWlucyBiZWxvbmdpbmcgdG8gdGhlIHNhbWUgZXZvbHV0aW9uIHRyZWF0bWVudC4gVGhlcmUgd2VyZSAxMiBsZXZlbHMgb2YgY3Jvc3MgbmVzdGVkIHdpdGhpbiBldm9sdXRpb24gdHJlYXRtZW50LCBmb3IgYSB0b3RhbCBvZiAzNiBjcm9zc2VzLiBXZSBrZXB0IHN1YnBvcHVsYXRpb25zIGZyb20gdGhlIHNhbWUgYENyb3NzYCBhbmQgYEJsb2NrYCBpbiB0aGUgc2FtZSBjb2x1bW4gb2YgdGhlIF9Ecm9zb3BoaWxhXyB2aWFsIHRyYXlzLCBzbyBpbmN1ZGluZyB0aGlzIHZhcmlhYmxlIGFsc28gY29udHJvbHMgZm9yIG1pY3JvLWVudmlyb25tZW50YWwgdmFyaWF0aW9uIGNhdXNlZCBieSB3aXRoaW4tdHJheSBwb3NpdGlvbi4gV2UgdXNlZCB0aGlzIHJhbmRvbSBlZmZlY3QgaW4gb3VyIGZpcnN0IG1vZGVsLgoKYE1vdGhlcl9zdHJhaW5gIGFuZCBgRmF0aGVyX3N0cmFpbmA6IFVzZWQgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gYENyb3NzYCBpbiBvdXIgc2Vjb25kIG1vZGVsLiBJbiB0aGlzIGNhc2UsIHdlIGZpdCBhIG11bHRpLW1lbWJlcnNoaXAgbW9kZWwsIHdoZXJlIGVhY2ggc3VicG9wdWxhdGlvbiBzaW11bHRhbmVvdXNseSBiZWxvbmdzIHRvIHR3byBsZXZlbHMgb2YgdGhlIGBDcm9zc2AgcmFuZG9tIGVmZmVjdC4gVGhhdCBpcywgZWFjaCBzdWJwb3B1bGF0aW9uIHdhcyBmb3VuZGVkIG15IGEgbW90aGVyIGZyb20gJHN0cmFpbl9pJCBhbmQgYSBmYXRoZXIgZnJvbSAkc3RyYWluX2okIGFuZCB0aGV5IHRoZXJlZm9yZSBhbHdheXMgYmVsb25nIHRvIHR3byBsZXZlbHMgb2Ygc3RyYWluLiAKCioqTXVsdGktbWVtYmVyc2hpcCB2cyBzaW5nbGUtbWVtYmVyc2hpcCoqCgpXaGlsZSB0aGUgbXVsdGktbWVtYmVyc2hpcCBhcHByb2FjaCBtYXkgaW5pdGlhbGx5IHNlZW0gdGhlIG1vcmUgcG93ZXJmdWwgb2YgdGhlIHR3byByYW5kb20gZWZmZWN0IHN0cnVjdHVyZXMsIHdlIGZhdm91ciB0aGUgc2luZ2xlLW1lbWJlcnNoaXAgYXBwcm9hY2ggZm9yIHNldmVyYWwgcmVhc29ucy4gRmlyc3QsIG91ciBwcmltYXJ5IGFpbSBpcyB0byBlc3RpbWF0ZSB0aGUgb3ZlcmFsbCBjYXVzYWwgZWZmZWN0IG9mIGV2b2x1dGlvbiB0cmVhdG1lbnQgb24gZ2VuZXJhdGlvbnMgdG8gZXh0aW5jdGlvbiwgcmF0aGVyIHRoYW4gdGhhdCBvZiBlYWNoIHN0cmFpbiAobmVzdGVkIHdpdGhpbiBldm9sdXRpb24gdHJlYXRtZW50KS4gR2l2ZW4gdGhhdCB3ZSBiYWxhbmNlZCBvdXIgY3Jvc3NpbmcgZGVzaWduIHNvIHRoYXQgZWFjaCBzdHJhaW4gaXMgZXF1YWxseSByZXByZXNlbnRlZCBpbiB0aGUgZXhwZXJpbWVudCwgZXN0aW1hdGlvbiBmb3IgZWFjaCBzdHJhaW4gaXMgbm90IGludGVncmFsLiBTZWNvbmQsIENyb3NzIGNhcHR1cmVzIG51aXNhbmNlIGVudmlyb25tZW50YWwgdmFyaWF0aW9uIHRoYXQgU3RyYWluIGRvZXMgbm90LiBXZSBkaXN0cmlidXRlZCBzdWJwb3B1bGF0aW9ucyB0aHJvdWdob3V0IHRocmVlIF9Ecm9zb3BoaWxhXyB2aWFsIHRyYXlzIGJ5IHBsYWNpbmcgc3VicG9wdWxhdGlvbnMgZnJvbSB0aGUgc2FtZSBjcm9zcyBpbiB0aGUgc2FtZSBjb2x1bW4uIEFjcm9zcyB0aGUgY29sdW1ucyB3ZSBzcGxpdCBzdWJwb3B1bGF0aW9ucyB1cCBieSBldm9sdXRpb24gdHJlYXRtZW50LCBzdWNoIHRoYXQgY29sdW1uIG9uZSBjb250YWluZWQgc3VicG9wdWxhdGlvbnMgZnJvbSB0aGUgZmVtYWxlLWxpbWl0ZWQgdHJlYXRtZW50LCBjb2x1bW4gdHdvIGNvbnRhaW5lZCBzdWJwb3B1bGF0aW9ucyBmcm9tIHRoZSBtYWxlLWxpbWl0ZWQgdHJlYXRtZW50IGFuZCBjb2x1bW4gdGhyZWUgY29udGFpbmVkIHN1YnBvcHVsYXRpb25zIGZyb20gdGhlIGNvbnRyb2wgdHJlYXRtZW50LiBXZSByZXBlYXRlZCB0aGlzIHBhdHRlcm4gdW50aWwgYWxsIDM2IGNyb3NzZXMgZmlsbGVkIGEgY29sdW1uLiBBcyBhIHN0cmFpbiBpcyB1c2VkIGluIG11bHRpcGxlIGNyb3NzZXMsIGl0IGlzIHdpZGVseSBkaXN0aXJidXRlZCB0aHJvdWdob3V0IHRoZSB0cmF5cyBhbmQgdGhlcmVmb3JlIGRvZXMgbm90IGNhcHR1cmUgYSBsb2NhdGlvbiBlZmZlY3QgbGlrZSBjcm9zcyBkb2VzLiBXZSBhcmUgb2YgdGhlIG9waW5pb24gdGhhdCBjb250cm9sbGluZyBmb3IgdGhpcyBlbnZpcm9ubWVudGFsIHZhcmlhdGlvbiBpcyBvZiBncmVhdGVyIGltcG9ydGFuY2UgdGhhbiBzdHJhaW4gbGV2ZWwgZGlmZmVyZW5jZXMgaW4gbXV0YXRpb24gbG9hZCwgd2hpY2ggYm90aCBjcm9zcyBhbmQgZXZvbHV0aW9uIHRyZWF0bWVudCBhbHNvIGNvbnRhaW4gaW5mb3JtYXRpb24gZm9yLgoKRmluYWxseSwgd2UgZml0IGJvdGggbW9kZWxzIGFuZCB1c2UgbGVhdmUgb25lIG91dCAoTE9PKSBjcm9zcyB2YWxpZGF0aW9uIHRvIGZvcm1hbGx5IGFzc2VzcyB3aGljaCBtb2RlbCBoYXMgYmV0dGVyIGV4cGVjdGVkIHByZWRpY3RpdmUgYWNjdXJhY3ksIGJvdGggaW4gYW5kIG91dCBvZiBzYW1wbGUuCgoqKlByaW9ycyoqCgpXZSBmaXQgbW9kZXJhdGVseSBpbmZvcm1hdGl2ZSBwcmlvcnMsIHdpdGggdGhlIGFpbSB0byByZWd1bGFyaXNlIG91ciBwb3N0ZXJpb3IgZXN0aW1hdGVzIGFuZCBpbXByb3ZlIG1vZGVsIGZpdHRpbmcgYnkgcnVsaW5nIG91dCBub24tc2Vuc2ljYWwgdmFsdWVzLgoKTm90ZSB0aGF0IGVhY2ggb2YgdGhlc2UgcHJpb3JzIGlzIGV4cHJlc3NlZCBvbiB0aGUgbG9nIHNjYWxlLCBkdWUgdG8gdGhlIHdlaWJ1bGwgbG9nIGxpbmsuCgokXGFscGhhJCAodGhlIGludGVyY2VwdHMpIH4gR2FtbWEoc2hhcGUgPSA1LCByYXRlID0gMykKClRoaXMgaW50ZXJjZXB0IHByaW9yIHByZWRpY3RzIGFuIGFwcHJvcHJpYXRlIHN0YXJ0aW5nIHBvaW50IGZvciBwZXIgZ2VuZXJhdGlvbiBleHRpbmN0aW9uIHJhdGUgb24gdGhlIGxvZyBzY2FsZS4KCiRcYmV0YSQgKHRoZSBmaXhlZCBlZmZlY3RzKSB+IE5vcm1hbCgkXG11JCA9IDAsICRcc2lnbWEkID0gMSkgCgokXHNpZ21hJCB+IEV4cG9uZW50aWFsKHJhdGUgPSAxKQoKJGskIChUaGUgd2VpYnVsbCBzaGFwZSBwYXJhbWV0ZXIpIH4gTm9ybWFsKCRcbXUkID0gMCwgJFxzaWdtYSQgPSAwLjUpIAoKCiMjIyBGaXQgdGhlIG1vZGVscwoKYGBge3J9CgpleHRpbmN0aW9uX21vZGVsX3NtIDwtCiAgYnJtKGRhdGEgPSBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQsCiAgICAgIGZhbWlseSA9IHdlaWJ1bGwsCiAgICAgIGJmKEdlbnNfdG9fZXh0aW5jdCB8IGNlbnMoQ2Vuc29yZWRfMikgfiAxICsgRXZvbHV0aW9uX3RyZWF0bWVudCArIEJsb2NrICsgKDF8Q3Jvc3MpLAogICAgICAgICBzaGFwZSB+IDEgKyBFdm9sdXRpb25fdHJlYXRtZW50ICsgQmxvY2spLAogICAgICAjIHRoaXMgaW50ZXJjZXB0IHByaW9yIHByZWRpY3RzIGFuIGFwcHJvcHJpYXRlIHN0YXJ0aW5nIHBvaW50IGZvciBwZXIgZ2VuIGV4dGluY3Rpb24gcmF0ZSBvbiB0aGUgbG9nIHNjYWxlCiAgICAgIHByaW9yID0gYyhwcmlvcihnYW1tYSg1LCAzKSwgY2xhc3MgPSBJbnRlcmNlcHQsIGxiID0gMCksICAKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSBiKSwKICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAwLjUpLCBjbGFzcyA9IGIsIGRwYXIgPSBzaGFwZSkpLCAKICAgICAgaXRlciA9IDgwMDAsIHdhcm11cCA9IDQwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwKICAgICAgc2VlZCA9IDEsIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gLjksIG1heF90cmVlZGVwdGggPSAxMCksCiAgICAgICBmaWxlID0gIkZpdHMvZXh0aW5jdGlvbl9tb2RlbCIpCgpleHRpbmN0aW9uX21vZGVsX3NtIDwtIGFkZF9jcml0ZXJpb24oZXh0aW5jdGlvbl9tb2RlbF9zbSwgY3JpdGVyaW9uID0gImxvbyIpCgojIHRoZSBtb2RlbCBkb2VzIG5vdCBjb252ZXJnZSB3aGVuIHdlIHRyeSBhbmQgZml0IGEgdHJlYXRtZW50ICogYmxvY2sgaW50ZXJhY3Rpb24KCmV4dGluY3Rpb25fbW9kZWxfbW0gPC0KICBicm0oZGF0YSA9IGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCwKICAgICAgZmFtaWx5ID0gd2VpYnVsbCwKICAgICAgYmYoR2Vuc190b19leHRpbmN0IHwgY2VucyhDZW5zb3JlZF8yKSB+IDEgKyBFdm9sdXRpb25fdHJlYXRtZW50ICsgQmxvY2sgKyAoMXxtbShNb3RoZXJfc3RyYWluLCBGYXRoZXJfc3RyYWluKSksCiAgICAgIHNoYXBlIH4gMSArIEV2b2x1dGlvbl90cmVhdG1lbnQgKyBCbG9jayksCiAgICAgICMgdGhpcyBpbnRlcmNlcHQgcHJpb3IgcHJlZGljdHMgYW4gYXBwcm9wcmlhdGUgc3RhcnRpbmcgcG9pbnQgZm9yIHBlciBnZW4gZXh0aW5jdGlvbiByYXRlIG9uIHRoZSBsb2cgc2NhbGUKICAgICAgcHJpb3IgPSBjKHByaW9yKGdhbW1hKDUsIDMpLCBjbGFzcyA9IEludGVyY2VwdCwgbGIgPSAwKSwgCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gYiksCiAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCksCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoMCwgMC41KSwgY2xhc3MgPSBiLCBkcGFyID0gc2hhcGUpKSwgCiAgICAgIGl0ZXIgPSA4MDAwLCB3YXJtdXAgPSA0MDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsCiAgICAgIHNlZWQgPSAyLCBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTgsIG1heF90cmVlZGVwdGggPSAxNSksCiAgICAgIGZpbGUgPSAiRml0cy9leHRpbmN0aW9uX21vZGVsX21tIikKCmV4dGluY3Rpb25fbW9kZWxfbW0gPC0gYWRkX2NyaXRlcmlvbihleHRpbmN0aW9uX21vZGVsX21tLCBjcml0ZXJpb24gPSAibG9vIikKCmBgYAoKJH4kCgojIyMgTW9kZWwgZGlhZ25vc3RpY3MKCiR+JAoKQ29tcGFyZSBtb2RlbHMgdXNpbmcgYExPT2AsIGEgYmF5ZXNpYW4gaW5mb3JtYXRpb24gY3JpdGVyaWEKCmBgYHtyfQpsb29fY29tcGFyZShleHRpbmN0aW9uX21vZGVsX3NtLCBleHRpbmN0aW9uX21vZGVsX21tKSAgJT4lIAogIGthYmxlKGRpZ2l0cyA9IDMpICU+JSAKICBrYWJsZV9zdHlsaW5nKCkKYGBgCgpUaGUgc2luZ2xlLW1lbWJlcnNoaXAgbW9kZWwgcGVyZm9ybXMgKnNsaWdodGx5KiBiZXR0ZXIuIFdlIHByZXNlbnQgcmVzdWx0cyBmcm9tIHRoaXMgbW9kZWwuCgpMZXRzIHNlZSBob3cgdGhlIG1vZGVsIHJlY2FwaXR1bGF0ZXMgdGhlIGRhdGEKCmBgYHtyfQpwcF9jaGVjayhleHRpbmN0aW9uX21vZGVsX3NtLCB0eXBlID0gImhpc3QiLCBuZHJhd3MgPSAxMSwgYmlud2lkdGggPSAxKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiR+JAoKIyMjIEludGVycHJldGluZyBtb2RlbCBvdXRwdXQKCiR+JAoKV2UgY2FuIGluaXRpYWxseSBpZ25vcmUgdGhlIGBzaGFwZWAgcGFyYW1ldGVyIGFuZCBmaW5kIHRoZSBtZWFuIHJhdGUgb2YgZXh0aW5jdGlvbiwgYXZlcmFnZWQgYWNyb3NzIGFsbCBnZW5lcmF0aW9ucywgdXNpbmcgdGhlIGVxdWF0aW9uCgokXGxhbWJkYT0gXGZyYWN7MX17ZV5cbXV9JAoKRmlyc3QgZmluZCBkaXN0cmlidXRpb25zIG9mICRcbXUkIGZvciBlYWNoIG9mIHRoZSB0aHJlZSB0cmVhdG1lbnRzLgoKYGBge3J9CgppbnZlcnNlX3JhdGVfd2VpYnVsbCA8LQogIGV4dGluY3Rpb25fbW9kZWxfc20gJT4lIAogIGFzX2RyYXdzX2RmKCkgJT4lIAogIHRyYW5zbXV0ZShgQ29udHJvbCBCMWAgPSBiX0ludGVyY2VwdCwgCiAgICAgICAgIGBGZW1hbGVfbGltaXRlZCBCMWAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudEZlbWFsZSwKICAgICAgICAgYE1hbGVfbGltaXRlZCBCMWAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUsCiAgICAgICAgIGBDb250cm9sIEIyYCA9IGJfSW50ZXJjZXB0ICsgYl9CbG9jazIsIAogICAgICAgICBgRmVtYWxlX2xpbWl0ZWQgQjJgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUgKyBiX0Jsb2NrMiwKICAgICAgICAgYE1hbGVfbGltaXRlZCBCMmAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUgKyBiX0Jsb2NrMikKCmBgYAoKTm93IGxldHMgcGx1ZyB0aGVzZSBkaXN0cmlidXRpb25zIGludG8gdGhlIGVxdWF0aW9uIHRvIGZpbmQgbWVhbiBlc3RpbWF0ZXMgb2YgJFxsYW1iZGEkLgoKYGBge3J9CiAgaW52ZXJzZV9yYXRlX3dlaWJ1bGwgJT4lIAogIG11dGF0ZShhY3Jvc3MoMTo2LCB+MSAvIGV4cCgueCkpKSAlPiUgCiAgbXV0YXRlKGFjcm9zcyhldmVyeXRoaW5nKCksIH5tZWFuKC54KSkpICU+JSAKICBkaXN0aW5jdCgpCmBgYAoKVGhpcyBpcyB0aGUgcmF0ZSBvZiBleHRpbmN0aW9uIHBlciBnZW5lcmF0aW9uLCBhdmVyYWdlZCBhY3Jvc3MgYWxsIGdlbmVyYXRpb25zLiBIb3dldmVyLCB0aGUgd2VpYnVsbCBmYW1pbHkgYWxsb3dzIGEgZHluYW1pYyByYXRlIHJhdGhlciB0aGUgdGhlIGNvbnN0YW50IHJhdGUgdGhhdCB0aGUgZXhwb25lbnRpYWwgY29uc3RyYWlucyBpdCB0by4KCkZvbGxvd2luZyB0aGUgYHZpZ25ldHRlKCJicm1zX2ZhbWlsaWVzIilgLCB0aGUgd2VpYnVsbCBzdXJ2aXZhbCBmdW5jdGlvbiBjYW4gYmUgZm91bmQgdXNpbmcgdGhlIGZvbGxvd2luZyB0cmFuc2Zvcm1hdGlvbjoKCiRcbGFtYmRhPSBcZnJhY3tlXlxtdX17XGdhbW1hKDEgKyBcZnJhY3sxfXtrfSl9JAoKd2hlcmUgJGskIGlzIHRoZSBzaGFwZSBwYXJhbWV0ZXIgZXN0aW1hdGVkIGluIGBicm1zYAoKVGhlbiB3ZSBjYW4gZmluZCBzdXJ2aXZhbCBhdCBnZW5lcmF0aW9uICR0JCB1c2luZwoKJFMgPSBlXnstKFxmcmFje3R9e1xsYW1iZGF9KV5rfSQKCldlIHBsdWcgaW4gYSB2ZWN0b3Igd2l0aCAxNjAwMCBkcmF3cyBmcm9tIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIGZvciAxKSAkXG11JCBvZiBlYWNoIGluaGVyaXRhbmNlIHRyZWF0bWVudCBhbmQgMikgJGskIHRoZSBzaGFwZSBwYXJhbWV0ZXIgdG8gZmluZCBkaXN0cmlidXRpb25zIG9mIHRoZSBwcm9wb3J0aW9uIG9mIHN1cnZpdmluZyBzdWJwb3B1bGF0aW9ucyBhdCBlYWNoIGdlbmVyYXRpb24uCgpgYGB7cn0KCiMgRmluZCBsYW1iZGEgZm9yIHRoZSB0aHJlZSB0cmVhdG1lbnRzLiAKCmxhbWJkYV93ZWlidWxsIDwtCiAgZXh0aW5jdGlvbl9tb2RlbF9zbSAlPiUgCiAgYXNfZHJhd3NfZGYoKSAlPiUgCiAgdHJhbnNtdXRlKGBDb250cm9sIEIxYCA9IGJfSW50ZXJjZXB0LCAKICAgICAgICAgICAgYEZlbWFsZV9saW1pdGVkIEIxYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50RmVtYWxlLAogICAgICAgICAgICBgTWFsZV9saW1pdGVkIEIxYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50TWFsZSwKICAgICAgICAgICAgYENvbnRyb2wgQjJgID0gYl9JbnRlcmNlcHQgKyBiX0Jsb2NrMiwgCiAgICAgICAgICAgIGBGZW1hbGVfbGltaXRlZCBCMmAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudEZlbWFsZSArIGJfQmxvY2syLAogICAgICAgICAgICBgTWFsZV9saW1pdGVkIEIyYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50TWFsZSArIGJfQmxvY2syLAogICAgICAgICAgICBzaGFwZV9jb250cm9sX0IxID0gZXhwKGJfc2hhcGVfSW50ZXJjZXB0KSwKICAgICAgICAgICAgc2hhcGVfZmVtYWxlX0IxID0gZXhwKGJfc2hhcGVfSW50ZXJjZXB0ICsgYl9zaGFwZV9Fdm9sdXRpb25fdHJlYXRtZW50RmVtYWxlKSwKICAgICAgICAgICAgc2hhcGVfbWFsZV9CMSA9IGV4cChiX3NoYXBlX0ludGVyY2VwdCArIGJfc2hhcGVfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUpLAogICAgICAgICAgICBzaGFwZV9jb250cm9sX0IyID0gZXhwKGJfc2hhcGVfSW50ZXJjZXB0ICsgYl9zaGFwZV9CbG9jazIpLAogICAgICAgICAgICBzaGFwZV9mZW1hbGVfQjIgPSBleHAoYl9zaGFwZV9JbnRlcmNlcHQgKyBiX3NoYXBlX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUgKyBiX3NoYXBlX0Jsb2NrMiksCiAgICAgICAgICAgIHNoYXBlX21hbGVfQjIgPSBleHAoYl9zaGFwZV9JbnRlcmNlcHQgKyBiX3NoYXBlX0V2b2x1dGlvbl90cmVhdG1lbnRNYWxlICsgYl9zaGFwZV9CbG9jazIpKSAlPiUgCiAgbXV0YXRlKENvbnRyb2xfbGFtYmRhX0IxID0gZXhwKGBDb250cm9sIEIxYCkgLyBnYW1tYSgxICsgMS9zaGFwZV9jb250cm9sX0IxKSwKICAgICAgICAgRmVtYWxlX2xhbWJkYV9CMSA9IGV4cChgRmVtYWxlX2xpbWl0ZWQgQjFgKSAvIGdhbW1hKDEgKyAxL3NoYXBlX2ZlbWFsZV9CMSksCiAgICAgICAgIE1hbGVfbGFtYmRhX0IxID0gZXhwKGBNYWxlX2xpbWl0ZWQgQjFgKSAvIGdhbW1hKDEgKyAxL3NoYXBlX21hbGVfQjEpLAogICAgICAgICBDb250cm9sX2xhbWJkYV9CMiA9IGV4cChgQ29udHJvbCBCMmApIC8gZ2FtbWEoMSArIDEvc2hhcGVfY29udHJvbF9CMiksCiAgICAgICAgIEZlbWFsZV9sYW1iZGFfQjIgPSBleHAoYEZlbWFsZV9saW1pdGVkIEIyYCkgLyBnYW1tYSgxICsgMS9zaGFwZV9mZW1hbGVfQjIpLAogICAgICAgICBNYWxlX2xhbWJkYV9CMiA9IGV4cChgTWFsZV9saW1pdGVkIEIyYCkgLyBnYW1tYSgxICsgMS9zaGFwZV9tYWxlX0IyKSkgJT4lIAogIHNlbGVjdChjb250YWlucyhjKCJsYW1iZGEiLCAic2hhcGUiKSkpCgojIE5vdyBmaW5kIHN1cnZpdmFsIHByb3BvcnRpb24gYXQgZ2VuZXJhdGlvbnMgMS0yOQoKV2VpYnVsbF9zdXJ2aXZhbF9jdXJ2ZSA8LSAKICBsYW1iZGFfd2VpYnVsbCAlPiUgCiAgbXV0YXRlKCNCbG9jayAxCiAgICBDb250cm9sXzBfQjEgID0gZXhwKC0oMC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksICAKICAgIENvbnRyb2xfMV9CMSAgPSBleHAoLSgxL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMl9CMSAgPSBleHAoLSgyL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfM19CMSAgPSBleHAoLSgzL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfNF9CMSAgPSBleHAoLSg0L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfNV9CMSAgPSBleHAoLSg1L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfNl9CMSAgPSBleHAoLSg2L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfN19CMSAgPSBleHAoLSg3L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfOF9CMSA9IGV4cCgtKDgvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF85X0IxID0gZXhwKC0oOS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzEwX0IxID0gZXhwKC0oMTAvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xMV9CMSA9IGV4cCgtKDExL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTJfQjEgPSBleHAoLSgxMi9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzEzX0IxID0gZXhwKC0oMTMvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xNF9CMSA9IGV4cCgtKDE0L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTVfQjEgPSBleHAoLSgxNS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzE2X0IxID0gZXhwKC0oMTYvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xN19CMSA9IGV4cCgtKDE3L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMThfQjEgPSBleHAoLSgxOC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzE5X0IxID0gZXhwKC0oMTkvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yMF9CMSA9IGV4cCgtKDIwL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjFfQjEgPSBleHAoLSgyMS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzIyX0IxID0gZXhwKC0oMjIvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yM19CMSA9IGV4cCgtKDIzL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjRfQjEgPSBleHAoLSgyNC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzI1X0IxID0gZXhwKC0oMjUvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yNl9CMSA9IGV4cCgtKDI2L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjdfQjEgPSBleHAoLSgyNy9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzI4X0IxID0gZXhwKC0oMjgvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yOV9CMSA9IGV4cCgtKDI5L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIEZlbWFsZV8wX0IxICA9IGV4cCgtKDAvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xX0IxICA9IGV4cCgtKDEvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yX0IxICA9IGV4cCgtKDIvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8zX0IxICA9IGV4cCgtKDMvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV80X0IxICA9IGV4cCgtKDQvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV81X0IxICA9IGV4cCgtKDUvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV82X0IxICA9IGV4cCgtKDYvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV83X0IxICA9IGV4cCgtKDcvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV84X0IxICA9IGV4cCgtKDgvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV85X0IxICA9IGV4cCgtKDkvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xMF9CMSAgPSBleHAoLSgxMC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzExX0IxICA9IGV4cCgtKDExL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMTJfQjEgID0gZXhwKC0oMTIvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xM19CMSAgPSBleHAoLSgxMy9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzE0X0IxICA9IGV4cCgtKDE0L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMTVfQjEgID0gZXhwKC0oMTUvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xNl9CMSAgPSBleHAoLSgxNi9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzE3X0IxICA9IGV4cCgtKDE3L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMThfQjEgID0gZXhwKC0oMTgvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xOV9CMSAgPSBleHAoLSgxOS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzIwX0IxICA9IGV4cCgtKDIwL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjFfQjEgPSBleHAoLSgyMS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzIyX0IxID0gZXhwKC0oMjIvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yM19CMSA9IGV4cCgtKDIzL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjRfQjEgPSBleHAoLSgyNC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzI1X0IxID0gZXhwKC0oMjUvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yNl9CMSA9IGV4cCgtKDI2L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjdfQjEgPSBleHAoLSgyNy9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzI4X0IxID0gZXhwKC0oMjgvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yOV9CMSA9IGV4cCgtKDI5L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBNYWxlXzBfQjEgICAgID0gZXhwKC0oMC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzFfQjEgICAgID0gZXhwKC0oMS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzJfQjEgICAgID0gZXhwKC0oMi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzNfQjEgICAgID0gZXhwKC0oMy9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzRfQjEgICAgID0gZXhwKC0oNC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzVfQjEgICAgID0gZXhwKC0oNS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzZfQjEgICAgID0gZXhwKC0oNi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzdfQjEgICAgID0gZXhwKC0oNy9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzhfQjEgICAgID0gZXhwKC0oOC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzlfQjEgICAgID0gZXhwKC0oOS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzEwX0IxICAgID0gZXhwKC0oMTAvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xMV9CMSAgICA9IGV4cCgtKDExL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTJfQjEgICAgPSBleHAoLSgxMi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzEzX0IxICAgID0gZXhwKC0oMTMvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xNF9CMSAgICA9IGV4cCgtKDE0L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTVfQjEgICAgPSBleHAoLSgxNS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzE2X0IxICAgID0gZXhwKC0oMTYvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xN19CMSAgICA9IGV4cCgtKDE3L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMThfQjEgICAgPSBleHAoLSgxOC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzE5X0IxICAgID0gZXhwKC0oMTkvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yMF9CMSAgICA9IGV4cCgtKDIwL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjFfQjEgPSBleHAoLSgyMS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzIyX0IxID0gZXhwKC0oMjIvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yM19CMSA9IGV4cCgtKDIzL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjRfQjEgPSBleHAoLSgyNC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzI1X0IxID0gZXhwKC0oMjUvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yNl9CMSA9IGV4cCgtKDI2L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjdfQjEgPSBleHAoLSgyNy9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzI4X0IxID0gZXhwKC0oMjgvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yOV9CMSA9IGV4cCgtKDI5L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgICMgQmxvY2sgMgogICAgQ29udHJvbF8wX0IyICA9IGV4cCgtKDAvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLCAgCiAgICBDb250cm9sXzFfQjIgID0gZXhwKC0oMS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzJfQjIgID0gZXhwKC0oMi9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzNfQjIgID0gZXhwKC0oMy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzRfQjIgID0gZXhwKC0oNC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzVfQjIgID0gZXhwKC0oNS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzZfQjIgID0gZXhwKC0oNi9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzdfQjIgID0gZXhwKC0oNy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzhfQjIgPSBleHAoLSg4L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfOV9CMiA9IGV4cCgtKDkvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xMF9CMiA9IGV4cCgtKDEwL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTFfQjIgPSBleHAoLSgxMS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzEyX0IyID0gZXhwKC0oMTIvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xM19CMiA9IGV4cCgtKDEzL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTRfQjIgPSBleHAoLSgxNC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzE1X0IyID0gZXhwKC0oMTUvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xNl9CMiA9IGV4cCgtKDE2L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTdfQjIgPSBleHAoLSgxNy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzE4X0IyID0gZXhwKC0oMTgvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xOV9CMiA9IGV4cCgtKDE5L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjBfQjIgPSBleHAoLSgyMC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzIxX0IyID0gZXhwKC0oMjEvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yMl9CMiA9IGV4cCgtKDIyL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjNfQjIgPSBleHAoLSgyMy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzI0X0IyID0gZXhwKC0oMjQvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yNV9CMiA9IGV4cCgtKDI1L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjZfQjIgPSBleHAoLSgyNi9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzI3X0IyID0gZXhwKC0oMjcvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yOF9CMiA9IGV4cCgtKDI4L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjlfQjIgPSBleHAoLSgyOS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBGZW1hbGVfMF9CMiAgPSBleHAoLSgwL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMV9CMiAgPSBleHAoLSgxL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMl9CMiAgPSBleHAoLSgyL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfM19CMiAgPSBleHAoLSgzL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfNF9CMiAgPSBleHAoLSg0L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfNV9CMiAgPSBleHAoLSg1L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfNl9CMiAgPSBleHAoLSg2L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfN19CMiAgPSBleHAoLSg3L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfOF9CMiAgPSBleHAoLSg4L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfOV9CMiAgPSBleHAoLSg5L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTBfQjIgID0gZXhwKC0oMTAvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xMV9CMiAgPSBleHAoLSgxMS9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzEyX0IyICA9IGV4cCgtKDEyL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTNfQjIgID0gZXhwKC0oMTMvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xNF9CMiAgPSBleHAoLSgxNC9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzE1X0IyICA9IGV4cCgtKDE1L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTZfQjIgID0gZXhwKC0oMTYvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xN19CMiAgPSBleHAoLSgxNy9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzE4X0IyICA9IGV4cCgtKDE4L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTlfQjIgID0gZXhwKC0oMTkvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yMF9CMiAgPSBleHAoLSgyMC9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzIxX0IyID0gZXhwKC0oMjEvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yMl9CMiA9IGV4cCgtKDIyL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjNfQjIgPSBleHAoLSgyMy9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzI0X0IyID0gZXhwKC0oMjQvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yNV9CMiA9IGV4cCgtKDI1L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjZfQjIgPSBleHAoLSgyNi9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzI3X0IyID0gZXhwKC0oMjcvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yOF9CMiA9IGV4cCgtKDI4L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjlfQjIgPSBleHAoLSgyOS9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgTWFsZV8wX0IyICAgICA9IGV4cCgtKDAvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xX0IyICAgICA9IGV4cCgtKDEvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yX0IyICAgICA9IGV4cCgtKDIvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8zX0IyICAgICA9IGV4cCgtKDMvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV80X0IyICAgICA9IGV4cCgtKDQvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV81X0IyICAgICA9IGV4cCgtKDUvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV82X0IyICAgICA9IGV4cCgtKDYvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV83X0IyICAgICA9IGV4cCgtKDcvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV84X0IyICAgICA9IGV4cCgtKDgvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV85X0IyICAgICA9IGV4cCgtKDkvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xMF9CMiAgICA9IGV4cCgtKDEwL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTFfQjIgICAgPSBleHAoLSgxMS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzEyX0IyICAgID0gZXhwKC0oMTIvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xM19CMiAgICA9IGV4cCgtKDEzL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTRfQjIgICAgPSBleHAoLSgxNC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzE1X0IyICAgID0gZXhwKC0oMTUvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xNl9CMiAgICA9IGV4cCgtKDE2L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTdfQjIgICAgPSBleHAoLSgxNy9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzE4X0IyICAgID0gZXhwKC0oMTgvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xOV9CMiAgICA9IGV4cCgtKDE5L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjBfQjIgICAgPSBleHAoLSgyMC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzIxX0IyID0gZXhwKC0oMjEvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yMl9CMiA9IGV4cCgtKDIyL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjNfQjIgPSBleHAoLSgyMy9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzI0X0IyID0gZXhwKC0oMjQvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yNV9CMiA9IGV4cCgtKDI1L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjZfQjIgPSBleHAoLSgyNi9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzI3X0IyID0gZXhwKC0oMjcvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yOF9CMiA9IGV4cCgtKDI4L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjlfQjIgPSBleHAoLSgyOS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMikpICU+JSAKICBzZWxlY3QoLWMoY29udGFpbnMoYygic2hhcGUiLCAibGFtYmRhIikpKSkKCldlaWJ1bGxfZXh0aW5jdGlvbl9lc3RpbWF0ZXNfbG9uZyA8LQogIFdlaWJ1bGxfc3Vydml2YWxfY3VydmUgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gZXZlcnl0aGluZygpLCBuYW1lc190byA9ICJFdm9sdXRpb24gdHJlYXRtZW50IiwgdmFsdWVzX3RvID0gIlByb3Bfc3VicG9wdWxhdGlvbnNfc3Vydml2aW5nIikgJT4lIAogIHNlcGFyYXRlKGBFdm9sdXRpb24gdHJlYXRtZW50YCwgaW50byA9IGMoIkV2b2x1dGlvbiB0cmVhdG1lbnQiLCAiR2VuZXJhdGlvbiIsICJCbG9jayIpLCBzZXAgPSAiXyIpICU+JSAKICAgIG11dGF0ZShgRXZvbHV0aW9uIHRyZWF0bWVudGAgPSBjYXNlX3doZW4oCiAgICBgRXZvbHV0aW9uIHRyZWF0bWVudGAgPT0gIkZlbWFsZSIgfiAiRmVtYWxlLWxpbWl0ZWQiLAogICAgYEV2b2x1dGlvbiB0cmVhdG1lbnRgID09ICJNYWxlIiB+ICJNYWxlLWxpbWl0ZWQiLAogICAgYEV2b2x1dGlvbiB0cmVhdG1lbnRgID09ICJDb250cm9sIiB+ICJDb250cm9sIgogICkpCgpgYGAKCiR+JAoKIyMjIENyZWF0ZSBGaWd1cmUgMQoKTWFrZSBwYW5lbCBhIG9mIEZpZ3VyZSAxCgpgYGB7cn0KIyB2YWx1ZXMgZnJvbSBGYWxjb25lciBhbmQgTWFja2F5IDE5OTYgcGcgOTAKCkluYnJlZWRpbmdfY29lZnMgPC0KICB0aWJibGUoR2VuZXJhdGlvbiA9IDA6MjAsCiAgICAgICAgIFByb2JhYmlsaXR5X2hvbW96eWdvdXMgPSBjKDAsIDAuMjUsIDAuMzc1LCAwLjUsIDAuNTk0LCAwLjY3MiwgMC43MzQsIDAuNzg1LCAwLjgyNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMC44NTksIDAuODg2LCAwLjkwOCwgMC45MjYsIDAuOTQsIDAuOTUxLCAwLjk2MSwgMC45NjgsIDAuOTc0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLjk3OSwgMC45ODMsIDAuOTg2KSwKICAgICAgICAgUHJvYmFiaWxpdHlfcG9wX2ZpeGF0aW9uID0gYygwLCAwLCAwLjA2MywgMC4xNzIsIDAuMjkzLCAwLjQwOSwgMC41MTIsIDAuNjAxLCAwLjY3NSwgMC43MzYsIDAuNzg1LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLjgyNiwgMC44NTksIDAuODg2LCAwLjkwOCwgMC45MjUsIDAuOTQsIDAuOTUxLCAwLjk2LCAwLjk2OCwgMC45NzUpKSAlPiUgCiAgbXV0YXRlKHNpbmdsZV9sb2N1c19oZXRlcm96eWdvc2l0eSA9IDEgLSBQcm9iYWJpbGl0eV9ob21venlnb3VzLAogICAgICAgICBzaW5nbGVfbG9jdXNfbm90X2ZpeGVkID0gMSAtIFByb2JhYmlsaXR5X3BvcF9maXhhdGlvbikgCgojIGZvciB0aGUgcGxvdCBhbm5vdGF0aW9ucwoKYXJyb3dzIDwtIAogIHRpYmJsZSgKICAgIHgxID0gMy4yLAogICAgeDIgPSA1LjYsCiAgICB5MSA9IDAuMjgsIAogICAgeTIgPSAwLjQ5KQoKIyBCbG9jayAxCgp3ZWlidWxsX3N1cnZfcGxvdF9CMSA8LSAKICBXZWlidWxsX2V4dGluY3Rpb25fZXN0aW1hdGVzX2xvbmcgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiQjEiKSAlPiUgCiAgZ3JvdXBfYnkoYEV2b2x1dGlvbiB0cmVhdG1lbnRgLCBHZW5lcmF0aW9uKSAlPiUgCiAgdGlkeWJheWVzOjptZWRpYW5fcWkoUHJvcF9zdWJwb3B1bGF0aW9uc19zdXJ2aXZpbmcsIC53aWR0aCA9IDAuNSkgJT4lIAogIG11dGF0ZShHZW5lcmF0aW9uID0gYXMubnVtZXJpYyhHZW5lcmF0aW9uKSkgJT4lIAogIGFycmFuZ2UoR2VuZXJhdGlvbikgJT4lIAogICMgcGxvdCEKICBnZ3Bsb3QoYWVzKHggPSBHZW5lcmF0aW9uKSkgKwogIGdlb21fbGluZShkYXRhID0gSW5icmVlZGluZ19jb2VmcywgYWVzKHkgPSBzaW5nbGVfbG9jdXNfbm90X2ZpeGVkKSwgbGluZXR5cGUgPSAzLCAKICAgICAgICAgICAgbGluZXdpZHRoID0gMiwgYWxwaGEgPSAxKSArCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSAubG93ZXIsIHltYXggPSAudXBwZXIsIGZpbGwgPSBgRXZvbHV0aW9uIHRyZWF0bWVudGApLAogICAgICAgICAgICAgIGFscGhhID0gMS8yKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gUHJvcF9zdWJwb3B1bGF0aW9uc19zdXJ2aXZpbmcsIGNvbG9yID0gYEV2b2x1dGlvbiB0cmVhdG1lbnRgKSwgbGluZXR5cGUgPTUsIGxpbmV3aWR0aCA9IDAuOCkgKwogIAogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDMuMiwgeSA9IDAuMjYsIHNpemUgPSA0LCBsYWJlbCA9ICJTaW5nbGUgbG9jdXMgcHJvYi4gb2YgaGV0ZXJvenlnb3NpdHkiKSArCiAgZ2VvbV9jdXJ2ZSgKICAgIGRhdGEgPSBhcnJvd3MsIGFlcyh4ID0geDEsIHkgPSB5MSwgeGVuZCA9IHgyLCB5ZW5kID0geTIpLAogICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMDgsICJpbmNoIikpLCBzaXplID0gMC43NSwKICAgIGNvbG9yID0gImdyYXkyMCIsIGN1cnZhdHVyZSA9IC0wLjMpICsKICAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSwgZ3VpZGUgPSAibm9uZSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCA1LCAxMCwgMTUsIDIwLCAyNSwgMzApLCBleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wMSwgMC4wMSkpLCBsaW1pdHMgPSBjKDAsIDIwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsIDAuMjUsIC41LCAwLjc1LCAxKSwgbGltaXRzID0gMDoxLCBleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wMSwgMC4wMSkpKSArCiAgbGFicyh4ID0gIkdlbmVyYXRpb25zIG9mIGluYnJlZWRpbmciLCB5ID0gIlByb3BvcnRpb24gb2Ygc3Vydml2aW5nIHN1YnBvcHVsYXRpb25zIiwgZmlsbCA9ICJJbmhlcml0YW5jZSB0cmVhdG1lbnQiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBsZWdlbmQgYmcKICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvdXIgPSAndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoLjk1LCAuOTUpLAogICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygicmlnaHQiLCAidG9wIiksCiAgICAgICAgbGVnZW5kLmJveC5qdXN0ID0gInJpZ2h0IiwKICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKDYsIDYsIDYsIDYpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpKQoKYGBgCgpXZSBjYW4gYWxzbyBwbG90IHRoZSBtZWFuIGdlbmVyYXRpb25zIHVudGlsIGV4dGluY3Rpb24gZm9yIGVhY2ggZXZvbHV0aW9uIHRyZWF0bWVudC4gU29tZSBkYXRhIHdyYW5nbGluZyBpcyBmaXJzdCBuZWVkZWQuCgpgYGB7cn0KCm5ld19kYXRhIDwtIGV4cGFuZF9ncmlkKAogIEV2b2x1dGlvbl90cmVhdG1lbnQgPSBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQkRXZvbHV0aW9uX3RyZWF0bWVudCwKICBCbG9jayA9IDE6MikgJT4lIAogIGRpc3RpbmN0KEV2b2x1dGlvbl90cmVhdG1lbnQsIEJsb2NrKSAlPiUKICBtdXRhdGUoa2V5ID0gcGFzdGUoIlYiLCAxOm4oKSwgc2VwID0gIiIpKQoKd2VpYnVsbF9lc3RpbWF0ZXMgPC0gCiAgZml0dGVkKGV4dGluY3Rpb25fbW9kZWxfc20sIG5ld2RhdGEgPSBuZXdfZGF0YSwKICAgICAgICAgcmVfZm9ybXVsYSA9IE5BLCBzdW1tYXJ5ID0gRikgJT4lICAjcm9idXN0ID0gVCkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICByZW5hbWUoYEZlbWFsZS1saW1pdGVkXzFgID0gVjEsIGBGZW1hbGUtbGltaXRlZF8yYCA9IFYyLCBgTWFsZS1saW1pdGVkXzFgID0gVjMsIGBNYWxlLWxpbWl0ZWRfMmAgPSBWNCwgQ29udHJvbF8xID0gVjUsIENvbnRyb2xfMiA9IFY2KQoKbWVhbl93ZWlidWxsX2VzdGltYXRlcyA8LSAKICB3ZWlidWxsX2VzdGltYXRlcyAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjYsIG5hbWVzX3RvID0gIkV2b2x1dGlvbiB0cmVhdG1lbnQiLCB2YWx1ZXNfdG8gPSAiZ2VuZXJhdGlvbnMiKSAlPiUgCiAgc2VwYXJhdGUoY29sID0gYEV2b2x1dGlvbiB0cmVhdG1lbnRgLCBpbnRvID0gYygiRXZvbHV0aW9uIHRyZWF0bWVudCIsICJCbG9jayIpLCBzZXAgPSAiXyIpCgoKIyBjYWxjdWxhdGUgY29udHJhc3RzCgp3ZWlidWxsX2NvbnRyYXN0c19CMSA8LQogIHdlaWJ1bGxfZXN0aW1hdGVzICU+JSAKICBtdXRhdGUoYEZlbWFsZSAtIENvbnRyb2xgID0gYEZlbWFsZS1saW1pdGVkXzFgIC0gQ29udHJvbF8xLAogICAgICAgICBgTWFsZSAtIEZlbWFsZWAgPSBgTWFsZS1saW1pdGVkXzFgIC0gYEZlbWFsZS1saW1pdGVkXzFgLAogICAgICAgICBgTWFsZSAtIENvbnRyb2xgID0gYE1hbGUtbGltaXRlZF8xYCAtIENvbnRyb2xfMSkgJT4lIAogIHNlbGVjdCgtYyhgTWFsZS1saW1pdGVkXzFgLCBDb250cm9sXzEsIGBGZW1hbGUtbGltaXRlZF8xYCwKICAgICAgICAgICAgYE1hbGUtbGltaXRlZF8yYCwgQ29udHJvbF8yLCBgRmVtYWxlLWxpbWl0ZWRfMmApKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gIkNvbnRyYXN0IiwgdmFsdWVzX3RvID0gImdlbmVyYXRpb25fZGlmZiIpCgp3ZWlidWxsX2NvbnRyYXN0c19CMiA8LQogIHdlaWJ1bGxfZXN0aW1hdGVzICU+JSAKICBtdXRhdGUoYEZlbWFsZSAtIENvbnRyb2xgID0gYEZlbWFsZS1saW1pdGVkXzJgIC0gQ29udHJvbF8yLAogICAgICAgICBgTWFsZSAtIEZlbWFsZWAgPSBgTWFsZS1saW1pdGVkXzJgIC0gYEZlbWFsZS1saW1pdGVkXzJgLAogICAgICAgICBgTWFsZSAtIENvbnRyb2xgID0gYE1hbGUtbGltaXRlZF8yYCAtIENvbnRyb2xfMikgJT4lIAogIHNlbGVjdCgtYyhgTWFsZS1saW1pdGVkXzFgLCBDb250cm9sXzEsIGBGZW1hbGUtbGltaXRlZF8xYCwKICAgICAgICAgICAgYE1hbGUtbGltaXRlZF8yYCwgQ29udHJvbF8yLCBgRmVtYWxlLWxpbWl0ZWRfMmApKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gIkNvbnRyYXN0IiwgdmFsdWVzX3RvID0gImdlbmVyYXRpb25fZGlmZiIpCmBgYAoKQ3JlYXRlIHBhbmVscyBiIGFuZCBjIG9mIEZpZ3VyZSAxCgpgYGB7cn0KIyBwbG90IHRoZSBtZWFucwoKIyBibG9jayAxCgpleHRfcDFfQjEgPC0gCiAgbWVhbl93ZWlidWxsX2VzdGltYXRlcyAlPiUgCiAgZmlsdGVyKEJsb2NrID09ICIxIikgJT4lIAogIGdncGxvdChhZXMoeCA9IGdlbmVyYXRpb25zLCB5ID0gYEV2b2x1dGlvbiB0cmVhdG1lbnRgKSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IGBFdm9sdXRpb24gdHJlYXRtZW50YCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUpICsgIyB3aWR0aCBpbmRpY2F0ZXMgdGhlIHVuY2VydGFpbnR5IGludGVydmFsczogaGVyZSB3ZSBoYXZlIDY2JSBhbmQgOTUlIGludGVydmFscyArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IGhlcmUgd2UgaGF2ZSA2NiUgYW5kIDk1JSBpbnRlcnZhbHMrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgNSkpICsKICBsYWJzKHggPSAiR2VuZXJhdGlvbnMgdGlsbCBleHRpbmN0aW9uIiwgeSA9ICJJbmhlcml0YW5jZSB0cmVhdG1lbnQiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoNCwgMTIsIDEpLCBsaW1pdHMgPSBjKDQsIDEyKSkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgojIHBsb3QgdGhlIGNvbnRyYXN0cwoKZXh0X3AyX0IxIDwtIAogIHdlaWJ1bGxfY29udHJhc3RzX0IxICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBnZW5lcmF0aW9uX2RpZmYsIHkgPSBmY3RfcmVsZXZlbChDb250cmFzdCwgIkZlbWFsZSAtIENvbnRyb2wiLCAiTWFsZSAtIEZlbWFsZSIsICJNYWxlIC0gQ29udHJvbCIpKSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IENvbnRyYXN0KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGNhcnRvX3BhbCg3LCAiUGVhY2giKVsyXSwgY2FydG9fcGFsKDcsICJQdXJwIilbMV0sIGNhcnRvX3BhbCg3LCAiVGVhbEdybiIpWzFdKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgY29sb3VyID0gImJsYWNrIiwgc2l6ZSA9IDEpICsKICBsYWJzKHggPSAiRGlmZi4gaW4gZ2VuZXJhdGlvbnMgdGlsbCBleHRpbmN0aW9uIiwgeSA9ICJUcmVhdG1lbnQgY29udHJhc3QiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoLTQsIDYsIDIpKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcsIGNvbG9yPU5BKSwgI3RyYW5zcGFyZW50IHBsb3QgYmcKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKYGBgCgpXZSBjYW4gYWxzbyBlc3RpbWF0ZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGV2b2x1dGlvbmFyeSB0cmVhdG1lbnRzIGluIHRoZSBwcm9wb3J0aW9uIG9mIHN1YnBvcHVsYXRpb25zIGV4dGFudCBpbiBlYWNoIGdlbmVyYXRpb24uIEJlbG93IHdlIGNhbGN1bGF0ZSBlYWNoIGNvbnRyYXN0IGFuZCBtYWtlIHBhbmVscyBkLCBlIGFuZCBmCgpgYGB7cn0KCiMgQmxvY2sgMQoKRGlmZmVyZW5jZV9nZW5zX0IxIDwtCiAgV2VpYnVsbF9zdXJ2aXZhbF9jdXJ2ZSAlPiUgCiAgc2VsZWN0KGNvbnRhaW5zKCJCMSIpKSAlPiUgCiAgbXV0YXRlKEcxX2RpZmYuYyA9IE1hbGVfMV9CMSAtIENvbnRyb2xfMV9CMSwKICAgICAgICAgRzFfZGlmZi5mID0gTWFsZV8xX0IxIC0gRmVtYWxlXzFfQjEsCiAgICAgICAgIEcxX2RpZmYuZmMgPSBGZW1hbGVfMV9CMSAtIENvbnRyb2xfMV9CMSwKICAgICAgICAgRzJfZGlmZi5jID0gTWFsZV8yX0IxIC0gQ29udHJvbF8yX0IxLAogICAgICAgICBHMl9kaWZmLmYgPSBNYWxlXzJfQjEgLSBGZW1hbGVfMl9CMSwKICAgICAgICAgRzJfZGlmZi5mYyA9IEZlbWFsZV8yX0IxIC0gQ29udHJvbF8yX0IxLAogICAgICAgICBHM19kaWZmLmMgPSBNYWxlXzNfQjEgLSBDb250cm9sXzNfQjEsCiAgICAgICAgIEczX2RpZmYuZiA9IE1hbGVfM19CMSAtIEZlbWFsZV8zX0IxLAogICAgICAgICBHM19kaWZmLmZjID0gRmVtYWxlXzNfQjEgLSBDb250cm9sXzNfQjEsCiAgICAgICAgIEc0X2RpZmYuYyA9IE1hbGVfNF9CMSAtIENvbnRyb2xfNF9CMSwKICAgICAgICAgRzRfZGlmZi5mID0gTWFsZV80X0IxIC0gRmVtYWxlXzRfQjEsCiAgICAgICAgIEc0X2RpZmYuZmMgPSBGZW1hbGVfNF9CMSAtIENvbnRyb2xfNF9CMSwKICAgICAgICAgRzVfZGlmZi5jID0gTWFsZV81X0IxIC0gQ29udHJvbF81X0IxLAogICAgICAgICBHNV9kaWZmLmYgPSBNYWxlXzVfQjEgLSBGZW1hbGVfNV9CMSwKICAgICAgICAgRzVfZGlmZi5mYyA9IEZlbWFsZV81X0IxIC0gQ29udHJvbF81X0IxLAogICAgICAgICBHNl9kaWZmLmMgPSBNYWxlXzZfQjEgLSBDb250cm9sXzZfQjEsCiAgICAgICAgIEc2X2RpZmYuZiA9IE1hbGVfNl9CMSAtIEZlbWFsZV82X0IxLAogICAgICAgICBHNl9kaWZmLmZjID0gRmVtYWxlXzZfQjEgLSBDb250cm9sXzZfQjEsCiAgICAgICAgIEc3X2RpZmYuYyA9IE1hbGVfN19CMSAtIENvbnRyb2xfN19CMSwKICAgICAgICAgRzdfZGlmZi5mID0gTWFsZV83X0IxIC0gRmVtYWxlXzdfQjEsCiAgICAgICAgIEc3X2RpZmYuZmMgPSBGZW1hbGVfN19CMSAtIENvbnRyb2xfN19CMSwKICAgICAgICAgRzhfZGlmZi5jID0gTWFsZV84X0IxIC0gQ29udHJvbF84X0IxLAogICAgICAgICBHOF9kaWZmLmYgPSBNYWxlXzhfQjEgLSBGZW1hbGVfOF9CMSwKICAgICAgICAgRzhfZGlmZi5mYyA9IEZlbWFsZV84X0IxIC0gQ29udHJvbF84X0IxLAogICAgICAgICBHOV9kaWZmLmMgPSBNYWxlXzlfQjEgLSBDb250cm9sXzlfQjEsCiAgICAgICAgIEc5X2RpZmYuZiA9IE1hbGVfOV9CMSAtIEZlbWFsZV85X0IxLAogICAgICAgICBHOV9kaWZmLmZjID0gRmVtYWxlXzlfQjEgLSBDb250cm9sXzlfQjEsCiAgICAgICAgIEcxMF9kaWZmLmMgPSBNYWxlXzEwX0IxIC0gQ29udHJvbF8xMF9CMSwKICAgICAgICAgRzEwX2RpZmYuZiA9IE1hbGVfMTBfQjEgLSBGZW1hbGVfMTBfQjEsCiAgICAgICAgIEcxMF9kaWZmLmZjID0gRmVtYWxlXzEwX0IxIC0gQ29udHJvbF8xMF9CMSwKICAgICAgICAgRzExX2RpZmYuYyA9IE1hbGVfMTFfQjEgLSBDb250cm9sXzExX0IxLAogICAgICAgICBHMTFfZGlmZi5mID0gTWFsZV8xMV9CMSAtIEZlbWFsZV8xMV9CMSwKICAgICAgICAgRzExX2RpZmYuZmMgPSBGZW1hbGVfMTFfQjEgLSBDb250cm9sXzExX0IxLAogICAgICAgICBHMTJfZGlmZi5jID0gTWFsZV8xMl9CMSAtIENvbnRyb2xfMTJfQjEsCiAgICAgICAgIEcxMl9kaWZmLmYgPSBNYWxlXzEyX0IxIC0gRmVtYWxlXzEyX0IxLAogICAgICAgICBHMTJfZGlmZi5mYyA9IEZlbWFsZV8xMl9CMSAtIENvbnRyb2xfMTJfQjEsCiAgICAgICAgIEcxM19kaWZmLmMgPSBNYWxlXzEzX0IxIC0gQ29udHJvbF8xM19CMSwKICAgICAgICAgRzEzX2RpZmYuZiA9IE1hbGVfMTNfQjEgLSBGZW1hbGVfMTNfQjEsCiAgICAgICAgIEcxM19kaWZmLmZjID0gRmVtYWxlXzEzX0IxIC0gQ29udHJvbF8xM19CMSwKICAgICAgICAgRzE0X2RpZmYuYyA9IE1hbGVfMTRfQjEgLSBDb250cm9sXzE0X0IxLAogICAgICAgICBHMTRfZGlmZi5mID0gTWFsZV8xNF9CMSAtIEZlbWFsZV8xNF9CMSwKICAgICAgICAgRzE0X2RpZmYuZmMgPSBGZW1hbGVfMTRfQjEgLSBDb250cm9sXzE0X0IxLAogICAgICAgICBHMTVfZGlmZi5jID0gTWFsZV8xNV9CMSAtIENvbnRyb2xfMTVfQjEsCiAgICAgICAgIEcxNV9kaWZmLmYgPSBNYWxlXzE1X0IxIC0gRmVtYWxlXzE1X0IxLAogICAgICAgICBHMTVfZGlmZi5mYyA9IEZlbWFsZV8xNV9CMSAtIENvbnRyb2xfMTVfQjEsCiAgICAgICAgIEcxNl9kaWZmLmMgPSBNYWxlXzE2X0IxIC0gQ29udHJvbF8xNl9CMSwKICAgICAgICAgRzE2X2RpZmYuZiA9IE1hbGVfMTZfQjEgLSBGZW1hbGVfMTZfQjEsCiAgICAgICAgIEcxNl9kaWZmLmZjID0gRmVtYWxlXzE2X0IxIC0gQ29udHJvbF8xNl9CMSwKICAgICAgICAgRzE3X2RpZmYuYyA9IE1hbGVfMTdfQjEgLSBDb250cm9sXzE3X0IxLAogICAgICAgICBHMTdfZGlmZi5mID0gTWFsZV8xN19CMSAtIEZlbWFsZV8xN19CMSwKICAgICAgICAgRzE3X2RpZmYuZmMgPSBGZW1hbGVfMTdfQjEgLSBDb250cm9sXzE3X0IxLAogICAgICAgICBHMThfZGlmZi5jID0gTWFsZV8xOF9CMSAtIENvbnRyb2xfMThfQjEsCiAgICAgICAgIEcxOF9kaWZmLmYgPSBNYWxlXzE4X0IxIC0gRmVtYWxlXzE4X0IxLAogICAgICAgICBHMThfZGlmZi5mYyA9IEZlbWFsZV8xOF9CMSAtIENvbnRyb2xfMThfQjEsCiAgICAgICAgIEcxOV9kaWZmLmMgPSBNYWxlXzE5X0IxIC0gQ29udHJvbF8xOV9CMSwKICAgICAgICAgRzE5X2RpZmYuZiA9IE1hbGVfMTlfQjEgLSBGZW1hbGVfMTlfQjEsCiAgICAgICAgIEcxOV9kaWZmLmZjID0gRmVtYWxlXzE5X0IxIC0gQ29udHJvbF8xOV9CMSwKICAgICAgICAgRzIwX2RpZmYuYyA9IE1hbGVfMjBfQjEgLSBDb250cm9sXzIwX0IxLAogICAgICAgICBHMjBfZGlmZi5mID0gTWFsZV8yMF9CMSAtIEZlbWFsZV8yMF9CMSwKICAgICAgICAgRzIwX2RpZmYuZmMgPSBGZW1hbGVfMjBfQjEgLSBDb250cm9sXzIwX0IxKSAlPiUgCiAgICAgICAgI0cyMV9kaWZmLmMgPSBNYWxlXzIxX0IxIC0gQ29udHJvbF8yMV9CMSwKICAgICAgICAjRzIxX2RpZmYuZiA9IE1hbGVfMjFfQjEgLSBGZW1hbGVfMjFfQjEsCiAgICAgICAgI0cyMV9kaWZmLmZjID0gRmVtYWxlXzIxX0IxIC0gQ29udHJvbF8yMV9CMSwKICAgICAgICAjRzIyX2RpZmYuYyA9IE1hbGVfMjJfQjEgLSBDb250cm9sXzIyX0IxLAogICAgICAgICNHMjJfZGlmZi5mID0gTWFsZV8yMl9CMSAtIEZlbWFsZV8yMl9CMSwKICAgICAgICAjRzIyX2RpZmYuZmMgPSBGZW1hbGVfMjJfQjEgLSBDb250cm9sXzIyX0IxLAogICAgICAgICNHMjNfZGlmZi5jID0gTWFsZV8yM19CMSAtIENvbnRyb2xfMjNfQjEsCiAgICAgICAgI0cyM19kaWZmLmYgPSBNYWxlXzIzX0IxIC0gRmVtYWxlXzIzX0IxLAogICAgICAgICNHMjNfZGlmZi5mYyA9IEZlbWFsZV8yM19CMSAtIENvbnRyb2xfMjNfQjEsCiAgICAgICAgI0cyNF9kaWZmLmMgPSBNYWxlXzI0X0IxIC0gQ29udHJvbF8yNF9CMSwKICAgICAgICAjRzI0X2RpZmYuZiA9IE1hbGVfMjRfQjEgLSBGZW1hbGVfMjRfQjEsCiAgICAgICAgI0cyNF9kaWZmLmZjID0gRmVtYWxlXzI0X0IxIC0gQ29udHJvbF8yNF9CMSwKICAgICAgICAjRzI1X2RpZmYuYyA9IE1hbGVfMjVfQjEgLSBDb250cm9sXzI1X0IxLAogICAgICAgICNHMjVfZGlmZi5mID0gTWFsZV8yNV9CMSAtIEZlbWFsZV8yNV9CMSwKICAgICAgICAjRzI1X2RpZmYuZmMgPSBGZW1hbGVfMjVfQjEgLSBDb250cm9sXzI1X0IxLAogICAgICAgICNHMjZfZGlmZi5jID0gTWFsZV8yNl9CMSAtIENvbnRyb2xfMjZfQjEsCiAgICAgICAgI0cyNl9kaWZmLmYgPSBNYWxlXzI2X0IxIC0gRmVtYWxlXzI2X0IxLAogICAgICAgICNHMjZfZGlmZi5mYyA9IEZlbWFsZV8yNl9CMSAtIENvbnRyb2xfMjZfQjEsCiAgICAgICAgI0cyN19kaWZmLmMgPSBNYWxlXzI3X0IxIC0gQ29udHJvbF8yN19CMSwKICAgICAgICAjRzI3X2RpZmYuZiA9IE1hbGVfMjdfQjEgLSBGZW1hbGVfMjdfQjEsCiAgICAgICAgI0cyN19kaWZmLmZjID0gRmVtYWxlXzI3X0IxIC0gQ29udHJvbF8yN19CMSwKICAgICAgICAjRzI4X2RpZmYuYyA9IE1hbGVfMjhfQjEgLSBDb250cm9sXzI4X0IxLAogICAgICAgICNHMjhfZGlmZi5mID0gTWFsZV8yOF9CMSAtIEZlbWFsZV8yOF9CMSwKICAgICAgICAjRzI4X2RpZmYuZmMgPSBGZW1hbGVfMjhfQjEgLSBDb250cm9sXzI4X0IxLAogICAgICAgICNHMjlfZGlmZi5jID0gTWFsZV8yX0IxIC0gQ29udHJvbF8yOV9CMSwKICAgICAgICAjRzI5X2RpZmYuZiA9IE1hbGVfMjlfQjEgLSBGZW1hbGVfMjlfQjEsCiAgICAgICAgI0cyOV9kaWZmLmZjID0gRmVtYWxlXzI5X0IxIC0gQ29udHJvbF8yOV9CMSkgJT4lIAogIHNlbGVjdChzdGFydHNfd2l0aCgiRyIpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gIkRpZmZlcmVuY2UgY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAic3Vydml2YWxfZGlmZiIpICU+JSAKICBzZXBhcmF0ZShgRGlmZmVyZW5jZSBjb250cmFzdGAsIGludG8gPSBjKCJHZW5lcmF0aW9uIiwgIkRpZmZlcmVuY2UgY29udHJhc3QiKSwgc2VwID0gIl8iKSAlPiUgCiAgbXV0YXRlKEdlbmVyYXRpb24gPSBhcy5udW1lcmljKHN0cl9yZW1vdmUoR2VuZXJhdGlvbiwgIkciKSkpCgoKIyBNYWtlIHRoZSB0aHJlZSBwbG90cwoKTGVhZl9wbG90X21jX0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX0IxICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYuYyIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJQdXJwIikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJNYWxlIC0gQ29udHJvbFxuUHJvcC4gc3VydiBzdWJwb3B1bGF0aW9ucyIsCiAgICAgICB5ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpIAoKTGVhZl9wbG90X21mX0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX0IxICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYuZiIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJUZWFsR3JuIikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJNYWxlIC0gRmVtYWxlXG5Qcm9wLiBzdXJ2IHN1YnBvcHVsYXRpb25zIiwKICAgICAgIHkgPSBOVUxMKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKTGVhZl9wbG90X2ZjX0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX0IxICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYuZmMiKSAlPiUgCiAgZ2dwbG90KGFlcyhzdXJ2aXZhbF9kaWZmLCBhcy5mYWN0b3IoR2VuZXJhdGlvbikpKSArCiAgc3RhdF9pbnRlcnZhbCgud2lkdGggPSBjKDAuMDUsIDAuNjYsIDAuOTUpLCAKICAgICAgICAgICAgICAgIGhlaWdodCA9IDEsIHNob3cubGVnZW5kID0gRikgKwogIHJjYXJ0b2NvbG9yOjpzY2FsZV9jb2xvcl9jYXJ0b19kKHBhbGV0dGUgPSAiUGVhY2giKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIkZlbWFsZSAtIENvbnRyb2xcblByb3AuIHN1cnYgc3VicG9wdWxhdGlvbnMiLAogICAgICAgeSA9IE5VTEwpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgpgYGAKCkNvbWJpbmUgdGhlIDYgcGFuZWxzCgpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEwfQood2VpYnVsbF9zdXJ2X3Bsb3RfQjEgLyAoZXh0X3AxX0IxICsgZXh0X3AyX0IxKSkgLyAoTGVhZl9wbG90X21jX0IxICsgTGVhZl9wbG90X21mX0IxICsgTGVhZl9wbG90X2ZjX0IxKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAnYScpICsgCiAgcGxvdF9sYXlvdXQoaGVpZ2h0cyA9IGMoMS41LCAxLCAxKSkKYGBgCioqRmlndXJlIDEqKi4gUGFuZWwgKiphKiogc2hvd3MgZXh0aW5jdGlvbiB0cmFqZWN0b3JpZXMgdW5kZXIgaW5jcmVhc2luZyBzdHJlc3MgZnJvbSBpbmJyZWVkaW5nLiBCYW5kcyBhcmUgNTAlIGNyZWRpYmxlIGludGVydmFscyB0byBhaWQgdmlzdWFsIGluc3BlY3Rpb24uIFRoZSBibGFjayBkb3R0ZWQgbGluZSBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCBhIHJhbmRvbWx5IHNlbGVjdGVkIGF1dG9zb21hbCBsb2N1cyByZW1haW5zIGhldGVyb3p5Z291cy4gKipiKiogc2hvd3MgdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gZm9yIHRoZSBudW1iZXIgb2YgZ2VuZXJhdGlvbnMgdGhhdCBzdWItcG9wdWxhdGlvbnMgZGVzY2VuZGVkIGZyb20gZWFjaCBpbmhlcml0YW5jZSB0cmVhdG1lbnQgc3Vydml2ZWQgaW5icmVlZGluZyBleHBvc3VyZS4gVGhlIHdoaXRlIHBvaW50IHNob3dzIHRoZSBtZWRpYW4gd2l0aCBhc3NvY2lhdGVkIDY2IGFuZCA5NSUgY3JlZGlibGUgaW50ZXJ2YWxzIGMgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGVhY2ggdHJlYXRtZW50IGluIGdlbmVyYXRpb25zIHN1cnZpdmVkLiAqKmQtZioqIHNob3cgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGVhY2ggdHJlYXRtZW50IGluIGdlbmVyYXRpb25zIHN1cnZpdmVkLCBlc3RpbWF0ZWQgc2VwYXJhdGVseSBmb3IgZWFjaCBnZW5lcmF0aW9uIG9mIGluYnJlZWRpbmcuIFRoZSBpbm5lcm1vc3QgY29sb3VyIGJhbmQgYXBwcm94aW1hdGVzIHRoZSBtZWRpYW4sIHdoaWxlIHRoZSBtaWRkbGUgYW5kIG91dGVybW9zdCBiYXJzIHNob3cgNjYgYW5kIDk1JSBjcmVkaWJsZSBpbnRlcnZhbHMuICAgCgokfiQKCiMjIFByb2R1Y3Rpdml0eSBhbmFseXNpcwoKJH4kCgpXZSBoYXZlIHNldmVyYWwgaHlwb3RoZXNlcyB0aGF0IHdlIHRlc3Qgd2l0aCB0aGUgcHJvZHVjdGl2aXR5IGRhdGEuIEZpcnN0LCBwcm9kdWN0aXZpdHkgc2hvdWxkIGJlIG5lZ2F0aXZlbHkgY29ycmVsYXRlZCB3aXRoIHRoZSBudW1iZXIgb2YgZ2VuZXJhdGlvbnMgaW5icmVlZGluZyBvY2N1cnMsIGR1ZSB0byBpbmJyZWVkaW5nIGRlcHJlc3Npb24uIEFzIG1lbnRpb25lZCBhYm92ZSwgdGhpcyBlZmZlY3Qgc2hvdWxkIGJlIHN0cm9uZ2VzdCBpbiB0aGUgZmlyc3QgfjEwIGdlbmVyYXRpb25zIG9mIHRoZSBleHBlcmltZW50LCBkdXJpbmcgd2hpY2ggZnVsbC1zaWJsaW5nIGluYnJlZWRpbmcgc2hvdWxkIGhhdmUgdGhlIGxhcmdlc3QgZWZmZWN0cyBvbiBnZW5vbWUgd2lkZSBoZXRlcm96eWdvc2l0eS4gQWZ0ZXIgdGhpcyBwb2ludCwgdGhlIGluYnJlZWRpbmcgY29lZmZpY2llbnQgd2lsbCBiZSAwLjg5LCB3aGlsZSBvdmVyIHRoZSBuZXh0IDEwIGdlbmVyYXRpb25zIGl0IHNob3VsZCBvbmx5IGluY3JlYXNlIGJ5IGEgZnVydGhlciAwLjEgdG8gMC45OS4gSGVuY2UsIHdlIGV4cGVjdCBwcm9kdWN0aXZpdHkgdG8gc3RhYmlsaXNlIGJldHdlZW4gdGhlIDEwdGggYW5kIDIwdGggZ2VuZXJhdGlvbnMsIGFzc3VtaW5nIHRoZSBzdWJwb3B1bGF0aW9uIGlzIHN0aWxsIGV4dGFudC4gU2Vjb25kLCBzdWJwb3B1bGF0aW9ucyBjYXJyeWluZyBhdXRvc29tZXMgdGhhdCBoYXZlIHJlc3BvbmRlZCB0byBzZWxlY3Rpb24gb24gbWFsZXMgc2hvdWxkIGV4aGliaXQgYSBzbWFsbGVyIGRyb3AgaW4gcHJvZHVjdGl2aXR5IGNvbXBhcmVkIHdpdGggc3VicG9wdWxhdGlvbnMgY2FycnlpbmcgdGhlIGZlbWFsZS1hZGFwdGVkIG9yIGNvbnRyb2wgYXV0b3NvbWVzLCBiZWNhdXNlIHRoZXkgaGF2ZSBhIGhpc3Rvcnkgb2Ygc3Ryb25nZXIgc2VsZWN0aW9uIHRoYXQgc2hvdWxkLCBpbiB0aGVvcnksIGhhdmUgcHVyZ2VkIHRoZSBnZW5vbWUgb2YgcmVjZXNzaXZlIGRlbGV0ZXJpb3VzIGFsbGVsZXMuCgojIyMgTG9hZCBpbiB0aGUgZGF0YQoKYGBge3J9CgpkYXRhIDwtCiAgcmVhZF9jc3YoIkRhdGEvUHJvZHVjdGl2aXR5X2RhdGEuY3N2IikgJT4lIAogIG11dGF0ZShXZWVrID0gY2FzZV93aGVuKAogICAgQmxvY2sgPT0gMSB+IEdlbmVyYXRpb24sCiAgICBCbG9jayA9PSAyIH4gR2VuZXJhdGlvbiArIDkpKQoKUHJvZHVjdGl2aXR5X2RhdGEgPC0gCiAgbGVmdF9qb2luKAogICAgZGF0YSwKICAgIAogICAgZGF0YSAlPiUgCiAgICAgIGRpc3RpbmN0KENyb3NzLCBSZXBsaWNhdGUpICU+JSAKICAgICAgcm93aWRfdG9fY29sdW1uKCJzdWJwb3B1bGF0aW9uIikKICApICU+JSAKICBzZWxlY3Qoc3VicG9wdWxhdGlvbiwgZXZlcnl0aGluZygpKSAlPiUgCiAgbXV0YXRlKGFjcm9zcygxOjcsIGFzLmZhY3RvciksCiAgICAgICAgIFdlZWsgPSBhcy5mYWN0b3IoV2VlayksCiAgICAgICAgIENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZyA9IEZlbWFsZV9vZmZzcHJpbmcgKyBNYWxlX29mZnNwcmluZywKICAgICAgICAgUHJlX3dpbmRvd19vZmZzcHJpbmcgPSBQcmVfd2luZG93X2ZlbWFsZV9vZmZzcHJpbmcgKyBQcmVfd2luZG93X21hbGVfb2Zmc3ByaW5nLAogICAgICAgICBUb3RhbF9mZW1hbGVfb2Zmc3ByaW5nID0gRmVtYWxlX29mZnNwcmluZyArIFByZV93aW5kb3dfZmVtYWxlX29mZnNwcmluZywKICAgICAgICAgVG90YWxfbWFsZV9vZmZzcHJpbmcgPSBNYWxlX29mZnNwcmluZyArIFByZV93aW5kb3dfbWFsZV9vZmZzcHJpbmcsCiAgICAgICAgIFRvdGFsX29mZnNwcmluZyA9IFRvdGFsX2ZlbWFsZV9vZmZzcHJpbmcgKyBUb3RhbF9tYWxlX29mZnNwcmluZykgJT4lIAogICMgSW4gb25lIGdlbmVyYXRpb24gb2YgdGhlIGV4cGVyaW1lbnQgKGIxID0gRzI0ICYgQjIgPSBHMTUpIHNpYmxpbmcgcGFpcnMgd2VyZSBzZXR1cCBhIGRheSBlYXJseSBhbmQgcmVtb3ZlZCBmcm9tIHRoZWlyIHZpYWxzIGF0IHRoZSByZWd1bGFyIHRpbWUsIG1lYW5pbmcgdGhhdCB0aGV5IGhhZCBhbiBleHRyYSBkYXkgdG8gcHJvZHVjZSBvZmZzcHJpbmcuIFRvIGNvcnJlY3QgZm9yIHRoaXMgd2UgbXVsdGlwbHkgb2Zmc3ByaW5nIGNvdW50cyBieSAwLjc1LgogIG11dGF0ZShDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcgPSBpZl9lbHNlKENvdW50X2NvbmRpdGlvbnMgPT0gIkV4dHJhIGRheSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZyAqIDAuNzUpLCAgQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nKSwKICAgICAgICAgIyBub3RlIHRoYXQgYmVjYXVzZSBldmVyeXRoaW5nIGlzIG1vdmVkIGEgZGF5IGVhcmx5LCBwcmUtd2luZG93IG9mZnNwcmluZyBjb3VudHMgd2lsbCBzdGlsbCBiZSBpbmZsYXRlZCBldmVuIGFmdGVyIHRoaXMgY29ycmVjdGlvbgogICAgICAgICBQcmVfd2luZG93X29mZnNwcmluZyA9IGlmX2Vsc2UoQ291bnRfY29uZGl0aW9ucyA9PSAiRXh0cmEgZGF5IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChQcmVfd2luZG93X29mZnNwcmluZyAqIDAuNzUpLCAgUHJlX3dpbmRvd19vZmZzcHJpbmcpKQogIAojIENvbWJpbmUgd2l0aCBtb3J0YWxpdHkgYW5kIGV4dGluY3Rpb24gZGF0YSB0byBmaWx0ZXIgb3V0IHZpYWxzIHRoYXQgd2VudCBleHRpbmN0IGJlY2F1c2Ugb2YgZmVtYWxlIG1vcnRhbGl0eQoKUHJvZHVjdGl2aXR5X21vcnRhbGl0eSA8LQogIGxlZnRfam9pbigKICAgIFByb2R1Y3Rpdml0eV9kYXRhICU+JSAKICAgICAgZmlsdGVyKEdlbmVyYXRpb24gPCAyMSksICMlPiUgb25seSBpbmNsdWRlIGRhdGEgY29sbGVjdGVkIG9uIHRoZSBmaXJzdCAyMCBnZW5lcmF0aW9ucyBvZiBpbmJyZWVkaW5nIChibG9jayAyJ3MgZW5kcG9pbnQpCiAgICBtb3J0YWxpdHlfZGF0YSAlPiUgc2VsZWN0KHN1YnBvcHVsYXRpb24sIEdlbmVyYXRpb24sIEZlbWFsZV9tb3J0YWxpdHkpCiAgKQoKIyBXZSBhbHNvIGluY2x1ZGUgYSBjb2x1bW4gdGhhdCBzcGVjaWZpZXMgaWYgYSBzdWJwb3B1bGF0aW9uIHdhcyBleHRpbmN0LiBUaGlzIG1lYW5zIHdlIGNhbiBlYXNpbHkgcmVtb3ZlIDAgdmFsdWVzIGZyb20gdGhlIGRhdGEgaWYgcmVxdWlyZWQuIFdlIGNhbiB1c2UgdGhlIGBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQkR2Vuc190b19leHRpbmN0YCBjb2x1bW4gdG8gaGVscCB1cyBoZXJlLiAKClByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuIDwtCiAgbGVmdF9qb2luKAogICAgUHJvZHVjdGl2aXR5X21vcnRhbGl0eSwgIAogICAgZXh0aW5jdGlvbl9kYXRhX3dyYW5nbGVkICU+JSAKICAgICAgc2VsZWN0KHN1YnBvcHVsYXRpb24sIEdlbnNfdG9fZXh0aW5jdCwgQ2Vuc29yZWRfbW9ydGFsaXR5KQogICkgJT4lIAogIG11dGF0ZShWaWFsX3NldHVwID0gaWZfZWxzZShHZW5lcmF0aW9uID4gR2Vuc190b19leHRpbmN0LCAiTm8iLCAiWWVzIikpICU+JSAKICBmaWx0ZXIoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nICE9ICJOQSIpCgojIHJlbW92ZSBtb3J0YWxpdHkgZXZlbnRzIGFuZCB0aGVpciBjb25zZXF1ZW5jZXMgaW4gbGF0ZXIgZ2VuZXJhdGlvbnMKClByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuXzIgPC0KICBQcm9kdWN0aXZpdHlfZGF0YV9jbGVhbiAlPiUKICBtdXRhdGUoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nID0gY2FzZV93aGVuKAogICAgQ2Vuc29yZWRfbW9ydGFsaXR5ID09IDEgJiBWaWFsX3NldHVwID09ICJObyIgfiBOQV9yZWFsXywKICAgIFRSVUUgfiBDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcpKSAlPiUgCiAgZmlsdGVyKCFpcy5uYShDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcpLAogICAgICAgICBGZW1hbGVfbW9ydGFsaXR5ICE9IDEgfCBpcy5uYShGZW1hbGVfbW9ydGFsaXR5KSkKCgojIENyZWF0ZSBhIGZ1bmN0aW9uIHRvIGJ1aWxkIEhUTUwgc2VhcmNoYWJsZSB0YWJsZXMKCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpewogIGRhdGF0YWJsZSgKICAgIGRmLCByb3duYW1lcz1GQUxTRSwKICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsCiAgICBleHRlbnNpb25zID0gYygiU2Nyb2xsZXIiLCAgIkJ1dHRvbnMiKSwKICAgIG9wdGlvbnMgPSBsaXN0KAogICAgICBkb20gPSAnQmZydGlwJywKICAgICAgZGVmZXJSZW5kZXI9VFJVRSwKICAgICAgc2Nyb2xsWD1UUlVFLCBzY3JvbGxZPTQwMCwKICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwKICAgICAgYnV0dG9ucyA9CiAgICAgICAgbGlzdCgncGFnZUxlbmd0aCcsICdjb2x2aXMnLCAnY3N2JywgbGlzdCgKICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLAogICAgICAgICAgcGFnZVNpemUgPSAnQTQnLAogICAgICAgICAgb3JpZW50YXRpb24gPSAnbGFuZHNjYXBlJywKICAgICAgICAgIGZpbGVuYW1lID0gJ1Byb2R1Y3Rpdml0eV9kYXRhX2NsZWFuXzInKSksCiAgICAgIHBhZ2VMZW5ndGggPSA4NTAwCiAgICApCiAgKQp9CgpteV9kYXRhX3RhYmxlKFByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuICU+JSAKICAgICAgICAgICAgICAgIHNlbGVjdChNb3RoZXJfc3RyYWluLCBGYXRoZXJfc3RyYWluLCBDcm9zcywgc3VicG9wdWxhdGlvbiwgQmxvY2ssIFdlZWssIEdlbmVyYXRpb24sIFRyZWF0bWVudCwgVmlhbF9zZXR1cCwgQ291bnRfY29uZGl0aW9ucywgRmVtYWxlX29mZnNwcmluZywgTWFsZV9vZmZzcHJpbmcsIENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZywgUHJlX3dpbmRvd19mZW1hbGVfb2Zmc3ByaW5nLCBQcmVfd2luZG93X21hbGVfb2Zmc3ByaW5nLCBQcmVfd2luZG93X29mZnNwcmluZywgVG90YWxfZmVtYWxlX29mZnNwcmluZywgVG90YWxfbWFsZV9vZmZzcHJpbmcsIFRvdGFsX29mZnNwcmluZykpCgpgYGAKCioqQ29sdW1uIGV4cGxhbmF0aW9ucyoqCgpgTW90aGVyIHN0cmFpbmA6IHdlIG1lYXN1cmVkIGV4dGluY3Rpb24gYW5kIHByb2R1Y3Rpdml0eSBvZiBmYW1pbGllcyBkZXJpdmVkIGZyb20gMzYgZGlmZmVyZW50IGNyb3NzZXMuIENyb3NzZXMgd2VyZSBvbmx5IGNvbmR1Y3RlZCBiZXR3ZWVuIHN0cmFpbnMgdGhhdCBleHBlcmllbmNlZCB0aGUgc2FtZSBgRXZvbHV0aW9uX3RyZWF0bWVudGAuIFRoaXMgY29sdW1uIHNob3dzIHRoZSBzdHJhaW4gdGhhdCB0aGUgZm91bmRpbmcgZmVtYWxlIG9mIHRoZSBzdWJwb3B1bGF0aW9uIHdhcyBkZXJpdmVkIGZyb20uCgpgRmF0aGVyIHN0cmFpbmA6IHdlIG1lYXN1cmVkIGV4dGluY3Rpb24gYW5kIHByb2R1Y3Rpdml0eSBvZiBmYW1pbGllcyBkZXJpdmVkIGZyb20gMzYgZGlmZmVyZW50IGNyb3NzZXMuIENyb3NzZXMgd2VyZSBvbmx5IGNvbmR1Y3RlZCBiZXR3ZWVuIHN0cmFpbnMgdGhhdCBleHBlcmllbmNlZCB0aGUgc2FtZSBldm9sdXRpb24gdHJlYXRtZW50LiBUaGlzIGNvbHVtbiBzaG93cyB0aGUgc3RyYWluIHRoYXQgdGhlIGZvdW5kaW5nIG1hbGUgb2YgdGhlIHN1YnBvcHVsYXRpb24gd2FzIGRlcml2ZWQgZnJvbS4KCmBDcm9zc2A6IGFuIGlkZW50aWZ5aW5nIElEIGZvciBlYWNoIG9mIHRoZSAzNiBjb21iaW5hdGlvbnMgb2YgYE1vdGhlciBzdHJhaW5gIGFuZCBgRmF0aGVyIHN0cmFpbmAuIAoKYHN1YnBvcHVsYXRpb25gOiBsaW5lcyBvZiBmbGllcyBmb3VuZGVkIGJ5IHNpbmdsZSBpbnNlbWluYXRlZCBmZW1hbGVzIGluIGdlbmVyYXRpb24gemVyby4gV2UgZ2VuZXJhdGVkIHRoZSBuZXh0IGdlbmVyYXRpb24gb2YgZWFjaCBzdWJwb3B1bGF0aW9uIGJ5IGNyb3NzaW5nIGEgc2luZ2xlIGZ1bGwtc2libGluZyBkeWFkLgoKYEJsb2NrYDogdGhlIGV4cGVyaW1lbnQgd2FzIHJ1biBpbiAyIGRpc3RpbmN0IGJsb2NrcywgdXNpbmcgZmxpZXMgc2VwYXJhdGVkIGJ5IDkgZ2VuZXJhdGlvbnMuIEJsb2NrIDEgcmFuIGZvciAyOSBnZW5lcmF0aW9ucywgd2hlcmVhcyBCbG9jayAyIHJhbiBmb3IgMjAgZ2VuZXJhdGlvbnMuCgpgV2Vla2A6IHRoZSB3ZWVrIHRoYXQgdGhlIGdlbmVyYXRpb24gb2YgZWFjaCBibG9jayB3YXMgY29uZHVjdGVkIGluLiBOb3RlIHRoYXQgYmxvY2tzIG92ZXJsYXAgYmV0d2VlbiB3ZWVrcyA5LTI5LgoKYEdlbmVyYXRpb25gOiB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgZXh0aW5jdGlvbiBhc3NheSwgcmFuZ2luZyBmcm9tIDEgdG8gMjAuIAoKYFRyZWF0bWVudGA6IHRoZSBzdHJhaW5zIGhhZCBiZWVuIGV4cG9zZWQgdG8gb25lIG9mIHRocmVlIGV2b2x1dGlvbmFyeSBjb25kaXRpb25zIGZvciAyMC0yOSBnZW5lcmF0aW9uczogYSBmZW1hbGUtbGltaXRlZCByZXNwb25zZSB0byBzZWxlY3Rpb24sIGEgbWFsZS1saW1pdGVkIHJlc3BvbnNlIGFuZCBhIGNvbnRyb2wgY29uZGl0aW9uIHdoZXJlIGFuIGV2b2x1dGlvbmFyeSByZXNwb25zZSBvY2N1cnJlZCBpbiBib3RoIHNleGVzLgoKYFZpYWwgc2V0dXBgOiBzcGVjaWZpZXMgd2hldGhlciBhIHZpYWwgd2FzIHNldHVwIGZvciBhIGdpdmVuIHN1YnBvcHVsYXRpb24gaW4gYSBnaXZlbiBnZW5lcmF0aW9uLiBWaWFscyB3ZXJlIG5vdCBzZXR1cCB3aGVuIHRoZSBzdWJwb3B1bGF0aW9uIHdhcyBleHRpbmN0LCBvciB3aGVuIGl0IGNvdWxkIG5vIGxvbmdlciBiZSBpbmNsdWRlZCBpbiB0aGUgZXhwZXJpbWVudCBkdWUgdG8gZXNjYXBlLyBoYW5kbGluZyBlcnJvci4KCmBDb3VudF9jb25kaXRpb25zYDogTm9ybWFsIGluZGljYXRlcyB0aGF0IHRoZSBicmVlZGluZyB3aW5kb3cgbGFzdGVkIHRoZSBzdGFuZGFyZCB0aHJlZSBkYXlzLiBFeHRyYSBkYXkgaW5kaWNhdGVzIHRoZSBicmVlZGluZyBwYWlyIHdlcmUgbGVmdCBpbiB0aGUgdmlhbCBmb3IgYW4gZXh0cmEgZGF5LiBUaGlzIG9jY3VycmVkIGR1cmluZyBnZW5lcmF0aW9uIDE1IG9mIHRoZSBzZWNvbmQgZXhwZXJpbWVudGFsIGJsb2NrLgoKYEZlbWFsZV9vZmZzcHJpbmdgOiB0aGUgbnVtYmVyIG9mIGFkdWx0IGZlbWFsZXMgcHJvZHVjZWQgYnkgdGhlIGJyZWVkaW5nIHBhaXIgdGhhdCBlY2xvc2VkIGR1cmluZyB0aGUgZm91ci1kYXkgY29sbGVjdGlvbiB3aW5kb3cKCmBNYWxlX29mZnNwcmluZ2A6IGFzIGFib3ZlLCBidXQgZm9yIG1hbGUgb2Zmc3ByaW5nLgoKYENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZ2A6IHRoZSBzdW0gb2YgYEZlbWFsZV9vZmZzcHJpbmdgIGFuZCBgTWFsZV9vZmZzcHJpbmdgLgoKYFByZV93aW5kb3dfZmVtYWxlX29mZnNwcmluZ2A6IGZlbWFsZXMgcHJvZ2VueSB0aGF0IGVjbG9zZWQgcHJpb3IgdG8gdGhlIGNvbGxlY3Rpb24gd2luZG93IG9wZW5pbmcuCgpgUHJlX3dpbmRvd19tYWxlX29mZnNwcmluZ2A6IGFzIGFib3ZlLCBidXQgZm9yIG1hbGUgb2Zmc3ByaW5nLgoKYFByZV93aW5kb3dfb2Zmc3ByaW5nYDogdGhlIHN1bSBvZiBgUHJlX3dpbmRvd19mZW1hbGVfb2Zmc3ByaW5nYCBhbmQgYFByZV93aW5kb3dfbWFsZV9vZmZzcHJpbmdgLgoKYFRvdGFsX2ZlbWFsZV9vZmZzcHJpbmdgOiB0aGUgc3VtIG9mIGBGZW1hbGVfb2Zmc3ByaW5nYCBhbmQgYFByZV93aW5kb3dfZmVtYWxlX29mZnNwcmluZ2AuCgpgVG90YWxfbWFsZV9vZmZzcHJpbmdgOiBhcyBhYm92ZSwgYnV0IGZvciBtYWxlIG9mZnNwcmluZy4KCmBUb3RhbF9vZmZzcHJpbmdgOiB0aGUgdG90YWwgbnVtYmVyIG9mIG9mZnNwcmluZyBwcm9kdWNlZCwgc3VtbWVkIGFjcm9zcyB0aGUgc2V4ZXMgYW5kIHRoZSBwcmUtd2luZG93IGFuZCB3aXRoaW4td2luZG93IGNvbGxlY3Rpb25zLgoKJH4kCgoqKkRvIG9mZnNwcmluZyBlbWVyZ2UgcHJpb3IgdG8gZGF5IDEwIHRocm91Z2hvdXQgdGhlIGV4cGVyaW1lbnQ/KioKCmBgYHtyfQogIFByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBHZW5lcmF0aW9uLCB5ID0gUHJlX3dpbmRvd19vZmZzcHJpbmcvVG90YWxfb2Zmc3ByaW5nKSkgKwogIGdlb21faml0dGVyKGFlcyhzaXplID0gVG90YWxfb2Zmc3ByaW5nKSwgY29sb3VyID0gbWV0LmJyZXdlcigiT0tlZWZmZTIiKVsyXSwgZmlsbCA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbM10sIHdpZHRoID0gMC4yLCAKICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBzdHJva2UgPTEsIGFscGhhID0gMC4yNSkgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDAsIDUpLCBuYW1lID0gIlRvdGFsIG9mZnNwcmluZyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpLCBleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wMSwgMC4wMSkpKSArCiAgdGhlbWVfdGlkeWJheWVzKCkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygxLCAyMCkpICsKICBsYWJzKHkgPSAiUHJvcC4gb2Zmc3ByaW5nIGVjbG9zaW5nIHByaW9yIHRvIGRheSAxMCIsIAogICAgICAgeCA9ICJHZW5lcmF0aW9uIG9mIGluYnJlZWRpbmciLAogICAgICAgKSArCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCioqRmlndXJlIFMzKiouIFJhdyBwcm9wb3J0aW9uIG9mIHByb2R1Y3Rpdml0eSB0aGF0IG9jY3VycmVkIHByaW9yIHRvIHRoZSBlY2xvc2lvbiB3aW5kb3csIGZvciB0aGUgZmlyc3QgMjAgZ2VuZXJhdGlvbnMgb2YgdGhlIGV4cGVyaW1lbnQuCgokfiQKCiMjIyBUZXN0aW5nIGZvciBvdXIgY2FzdWFsIGVmZmVjdAoKJH4kCgojIyMjIE1vZGVsbGluZyBhcHByb2FjaAoKQXMgbWVudGlvbmVkIGFib3ZlLCB3ZSBoYXZlIHN0cm9uZyBleHBlY3RhdGlvbnMgZm9yIGhvdyBmdWxsLXNpYmxpbmcgaW5icmVlZGluZyBzaG91bGQgYWZmZWN0IHByb2R1Y3Rpdml0eS4gRGVjcmVhc2luZyBnZW5vbWUtd2lkZSBoZXRlcm96eWdvc2l0eSBhbmQgdGhlIGV4cHJlc3Npb24gb2YgcmVjZXNzaXZlIGRlbGV0ZXJpb3VzIGFsbGVsZXMgdGhhdCBjb21lcyB3aXRoIHRoaXMgc2hvdWxkIGZvbGxvdyBhIHBhdHRlcm4gb2YgZXhwb25lbnRpYWwgZGVjYXkuIFRoaXMgbm9uLWxpbmVhciBwcm9jZXNzIGNhbiBiZSBtb2RlbGxlZCB1c2luZyB0aGUgYGJybXNgIG5vbi1saW5lYXIgc3ludGF4LiAKCkhlcmUgd2UgbW9kZWwgdGhlIHByb2R1Y3Rpdml0eSBhdCBnZW5lcmF0aW9uICR0JCB2aWEgdGhlIGZ1bmN0aW9uICRhIC0gZV57XGxhbWJkYSB0fSQgd2hlcmUgJGEkIGFuZCAkXGxhbWJkYSQgYXJlIHBhcmFtZXRlcnMgdGhhdCBjb250cm9sIHRoZSBpbml0aWFsIHByb2R1Y3Rpdml0eSBhbmQgdGhlIHJhdGUgb2YgaXRzIGRlY2F5IGFzIGdlbmVyYXRpb25zIG9mIGluYnJlZWRpbmcgcHJvZ3Jlc3MuIFdlIGZvcmNlICRhJCB0byBiZSBwb3NpdGl2ZSB1c2luZyB0aGUgYGV4cCgpYCBmdW5jdGlvbiwgd2hpY2ggZXhwcmVzc2VzIGl0IG9uIHRoZSBleHBvbmVudGlhbCBzY2FsZS4gTGFyZ2UgJGEkIGluZGljYXRlcyBoaWdoZXIgc3RhcnRpbmcgcHJvZHVjdGl2aXR5IGF0IGdlbmVyYXRpb24gMCAod2Ugc3RhcnRlZCBvYnNlcnZhdGlvbiBhdCBnZW5lcmF0aW9uIDEsIHRoZSBwcm9kdWN0aXZpdHkgZm9yIHdoaWNoIGlzIGdpdmVuIGJ5ICRhIC0gZV57XGxhbWJkYX0kKS4gUG9zaXRpdmUgdmFsdWVzIG9mICRcbGFtYmRhJCBpbmRpY2F0ZSB0aGF0IHByb2R1Y3Rpdml0eSBkZWNsaW5lcyB3aXRoIGluYnJlZWRpbmcsIHdoaWNoIGlzIG91ciBzdHJvbmcgZXhwZWN0YXRpb24gYW5kIGNsZWFybHkgdGhlIGNhc2UgZm9sbG93aW5nIGluc3BlY3Rpb24gb2YgdGhlIHJhdyBkYXRhIChzZWUgRmlndXJlIFNYKS4gCgpXZSBtb2RlbCBpbmJyZWVkaW5nIGRlcHJlc3Npb24gd2hpbGUgaW5jbHVkaW5nIHplcm8gdmFsdWVzIGZvciBhbGwgcm93cyB3aGVyZSBhIHN1YnBvcHVsYXRpb24gd2FzIGV4dGluY3QuIFRoaXMgaGVscHMgY29tYmF0IHVuZGVyZXN0aW1hdGlvbiBvZiB0aGUgZGVjYXkgcGFyYW1ldGVyLCBjYXVzZWQgYnkgdGhlIG5vbi1yYW5kb20gZXh0aW5jdGlvbiBvZiBzdWJwb3B1bGF0aW9ucywgd2hlcmUgaGlnaCBmaXRuZXNzIHN1YnBvcHVsYXRpb25zIGJlY29tZSBvdmVyLXJlcHJlc2VudGVkIGFzIHRoZSBnZW5lcmF0aW9ucyBvZiBpbmJyZWVkaW5nIHByb2dyZXNzIChpLmUuIHNlbGVjdGlvbikuIAoKKipGaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMqKgoKSW4gdGhlIGBicm1zYCBub24tbGluZWFyIHN5bnRheCwgZGlmZmVyZW50IGZvcm11bGFzIGNhbiBiZSBmaXQgZm9yIGVhY2ggcGFyYW1ldGVyLiBXZSBmaXQgdGhlIHNhbWUgZml4ZWQgZWZmZWN0IGZvciAkYSQgYW5kICRcbGFtYmRhJDogYEV2b2x1dGlvbiB0cmVhdG1lbnRgLiBXZSBmaXQgYHN1YnBvcHVsYXRpb25gIGFzIGEgcmFuZG9tIGVmZmVjdCB0byBhY2NvdW50IGZvciByZXBlYXRlZCBtZWFzdXJlbWVudHMgdGFrZW4gb24gZWFjaCBzdWJwb3B1bGF0aW9uIGZvciAkYSQsIGJ1dCBhcmUgdW5hYmxlIHRvIGRvIHRoaXMgZm9yICRcbGFtYmRhJCwgYXMgaW5kaXZpZHVhbCBzdWJwb3B1bGF0aW9uIHByb2R1Y3Rpdml0eSBjdXJ2ZXMgYXJlIGhpZ2hseSBoZXRlcm9za2VkYXN0aWMsIGFuZCBhcmUgc2tld2VkIGJ5IGV4dGluY3Rpb24gZXZlbnRzLiBUbyBtaW5pbWlzZSBwc2V1ZG9yZXBsaWNhdGlvbiBmb3IgJFxsYW1iZGEkLCB3ZSBmaXQgYENyb3NzYCBhcyBhIHJhbmRvbSBlZmZlY3QsIGFzIHdlIGRvIGZvciB0aGUgZXh0aW5jdGlvbiBkYXRhLiBXZSBhbHNvIGZpdCBgV2Vla2AgYXMgYSByYW5kb20gZWZmZWN0IGZvciBib3RoIHBhcmFtZXRlcnM7IHRoaXMgY29udHJvbHMgZm9yIGVudmlyb25tZW50YWwgdmFyaWF0aW9uIGJldHdlZW4gZ2VuZXJhdGlvbnMuCgoqKlByaW9ycyoqCgpXZSBmaXQgbW9kZXJhdGVseSBpbmZvcm1hdGl2ZSBwcmlvcnMsIHdpdGggdGhlIGFpbSB0byByZWd1bGFyaXNlIG91ciBwb3N0ZXJpb3IgZXN0aW1hdGVzIGFuZCBpbXByb3ZlIG1vZGVsIGZpdHRpbmcgYnkgcnVsaW5nIG91dCBub24tc2Vuc2ljYWwgdmFsdWVzLiBOb3RlIHRoYXQgcHJpb3JzIGFyZSBwYXJ0aWN1bGFybHkgaW1wb3J0YW50IHdoZW4gZml0dGluZyBub24tbGluZWFyIG1vZGVscy4KCk5vdGUgdGhhdCAkXGFscGhhJCByZWxhdGVkIHByaW9ycyBhcmUgZXhwcmVzc2VkIG9uIHRoZSBleHBvbmVudGlhbCBzY2FsZS4KCiRcYWxwaGEkIChpbml0aWFsIHByb2R1Y3Rpdml0eSkgfiBOb3JtYWwoJFxtdSQgPSA0LjIsICRcc2lnbWEkID0gMC4yNSkKCiRcbGFtYmRhJCAodGhlIHJhdGUgb2YgZGVjYXkpIH4gR2FtbWEoc2hhcGUgPSAwLjgsIHJhdGUgPSA0KSAKCiRcc2lnbWEkIGZvciAkXGFscGhhJCB+IEdhbW1hKHNoYXBlID0gMiwgcmF0ZSA9IDEuNSkKCiRcc2lnbWEkIGZvciAkXGxhbWJkYSQgfiBHYW1tYShzaGFwZSA9IDAuMjUsIHJhdGUgPSAyKQoKJH4kCgojIyMjIFNpbXVsYXRlIHRoZSBjdXJ2ZSwgd2l0aCB0aGUgcHJpb3JzIHdlIHdpbGwgc3BlY2lmeQoKUHJpb3IgcHJlZGljdGl2ZSBzaW11bGF0aW9uIGZvciB0aGUgcHJvZHVjdGl2aXR5IGRlY2xpbmUgbW9kZWwuIFRoZSBwbG90IHNob3dzIHRoZSByZXN1bHRzIGZyb20gMTAwIHByaW9yIGRyYXdzLgoKYGBge3J9CgpuIDwtIDFlNAoKIyBkZWZpbmUgdGhlIHgtYXhpcyBicmVha3MKYXQgPC0gMToyMAoKIyBob3cgbWFueSBwcmlvciBkcmF3cyB3b3VsZCB5b3UgbGlrZT8Kbl9kcmF3cyA8LSAyMDAKCiMgc2ltdWxhdGUKc2V0LnNlZWQoMTYpCgpwcmlvciA8LQogIHRpYmJsZShpbmRleCA9IDE6biwKICAgICAgICAgYSAgID0gcm5vcm0obiwgbWVhbiA9IDQuMiwgc2QgPSAwLjI1KSwKICAgICAgICAgbGFtYmRhID0gcmdhbW1hKG4sIDAuOCwgNCkpICU+JSAKICBzbGljZV9zYW1wbGUobiA9IG5fZHJhd3MpICU+JSAKICBleHBhbmQobmVzdGluZyhpbmRleCwgYSwgbGFtYmRhKSwKICAgICAgICAgR2VuZXJhdGlvbiA9IHNlcShmcm9tID0gMCwgdG8gPSAyMCwgbGVuZ3RoLm91dCA9IDFlMikpICU+JSAKICBtdXRhdGUocHJvZHVjdGl2aXR5ID0gZXhwKGEgLSBsYW1iZGEgKiBHZW5lcmF0aW9uKSkgCgoKcHJpb3IgJT4lIAogIGdncGxvdChhZXMoeCA9IEdlbmVyYXRpb24sIHkgPSBwcm9kdWN0aXZpdHksIGdyb3VwID0gaW5kZXgpKSArCiAgZ2VvbV9saW5lKHNpemUgPSAxLzIsIGFscGhhID0gMS80LCBjb2xvdXIgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiKVsyXSkgKwogIHRoZW1lX3RpZHliYXllcygpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDIwMCksIGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLCAuMSkpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwyMCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBsYWJzKHkgPSAic3VicG9wdWxhdGlvbiBwcm9kdWN0aXZpdHkiLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpCgpgYGAKCiR+JAoKIyMjIyBGaXQgdGhlIG5vbi1saW5lYXIgbW9kZWwKCmBgYHtyfQoKbm9ubGluZWFyX3Byb2R1Y3Rpdml0eSA8LSAKICBicm0oYmYoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nIH4gZXhwKGEgLSAobGFtYmRhICogR2VuZXJhdGlvbikpLAogICAgICAgICBhIH4gMSArIFRyZWF0bWVudCArICgxfFdlZWspICsgKDF8c3VicG9wdWxhdGlvbiksIAogICAgICAgICBsYW1iZGEgfiAxICsgVHJlYXRtZW50ICsgKDF8V2VlaykgKyAoMXxDcm9zcyksIAogICAgICAgICBubCA9IFRSVUUpLAogICAgICBkYXRhID0gUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW4sCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoNC4yLCAwLjI1KSwgY2xhc3MgPSBiLCBjb2VmID0gSW50ZXJjZXB0LCBubHBhciA9ICJhIiksCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoMCwgMC4yNSksIGNsYXNzID0gYiwgY29lZiA9IFRyZWF0bWVudEZlbWFsZSwgbmxwYXIgPSAiYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDAuMjUpLCBjbGFzcyA9IGIsIGNvZWYgPSBUcmVhdG1lbnRNYWxlLCBubHBhciA9ICJhIiksCiAgICAgICAgICAgICAgICBwcmlvcihnYW1tYSgwLjgsIDQpLCBjbGFzcyA9IGIsIGNvZWYgPSBJbnRlcmNlcHQsIG5scGFyID0gImxhbWJkYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDAuMiksIGNsYXNzID0gYiwgY29lZiA9IFRyZWF0bWVudEZlbWFsZSwgbmxwYXIgPSAibGFtYmRhIiksCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoMCwgMC4yKSwgY2xhc3MgPSBiLCBjb2VmID0gVHJlYXRtZW50TWFsZSwgbmxwYXIgPSAibGFtYmRhIiksCiAgICAgICAgICAgICAgICBwcmlvcihnYW1tYSgyLCAxLjUpLCBjbGFzcyA9IHNkLCBubHBhciA9ICJhIiksCiAgICAgICAgICAgICAgICBwcmlvcihnYW1tYSgwLjI1LCAyKSwgY2xhc3MgPSBzZCwgbmxwYXIgPSAibGFtYmRhIikpLAogICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOSwgbWF4X3RyZWVkZXB0aCA9IDEyKSwgc2VlZCA9IDUsCiAgICAgIGl0ZXIgPSAyMDAwMCwgd2FybXVwID0gNTAwMCwgY2hhaW5zID0gNCwgY29yZXMgPSA0LAogICAgICBmaWxlID0gIkZpdHMvbm9uX2xpbmVhcl9wcm9kdWN0aXZpdHlfbW9kZWxfbm9fZmFtIikKCmBgYAoKJH4kCgojIyMjIEJ1aWxkIGZpZ3VyZSAyCgokfiQKCmBgYHtyfQoKCm5ld19kYXRhIDwtIAogIFByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuXzIgJT4lIAogIHNlbGVjdChHZW5lcmF0aW9uLCBUcmVhdG1lbnQpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgbXV0YXRlKGtleSA9IHBhc3RlKCJWIiwgMTpuKCksIHNlcCA9ICIiKSkKCnByZWRzIDwtIAogIGFzLmRhdGEuZnJhbWUoZml0dGVkKG5vbmxpbmVhcl9wcm9kdWN0aXZpdHksIG5ld2RhdGEgPSBuZXdfZGF0YSwgcmVfZm9ybXVsYSA9IE5BLCBzdW1tYXJ5PUYpKSAlPiUgCiAgbXV0YXRlKGRyYXcgPSAxOm4oKSkgJT4lIAogIGdhdGhlcihrZXksIENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZywgLWRyYXcpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgbGVmdF9qb2luKG5ld19kYXRhLCBieSA9ICJrZXkiKSAlPiUgCiAgc2VsZWN0KC1rZXkpICU+JSAKICAgIG11dGF0ZShUcmVhdG1lbnQgPSBjYXNlX3doZW4oCiAgICBUcmVhdG1lbnQgPT0gIkZlbWFsZSIgfiAiRmVtYWxlLWxpbWl0ZWQiLAogICAgVHJlYXRtZW50ID09ICJNYWxlIiB+ICJNYWxlLWxpbWl0ZWQiLAogICAgVHJlYXRtZW50ID09ICJDb250cm9sIiB+ICJDb250cm9sIikpCgpwcmVkc19zdW1tYXJ5IDwtCiAgcHJlZHMgJT4lIAogIGdyb3VwX2J5KFRyZWF0bWVudCwgR2VuZXJhdGlvbikgJT4lCiAgbWVkaWFuX3FpKENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZywgLndpZHRoID0gMC41KQoKbmxfcDEgPC0KICBQcm9kdWN0aXZpdHlfZGF0YV9jbGVhbl8yICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBHZW5lcmF0aW9uLCB5ID0gQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nKSkgKwogIGdlb21faml0dGVyKGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbMl0sIHdpZHRoID0gMC4yNSwgCiAgICAgICAgICAgICAgc2hhcGUgPSAxLjUsIHN0cm9rZSA9Miwgc2l6ZSA9IDEuMiwgYWxwaGEgPSAwLjIpICsKICMgZ2VvbV9zbW9vdGgoc2l6ZSA9IDEuNSwgY29sb3VyID0gbWV0LmJyZXdlcigiT0tlZWZmZTIiKVs3XSwgYWxwaGEgPSAwLjQpICsKICBnZW9tX3JpYmJvbihkYXRhID0gcHJlZHNfc3VtbWFyeSwgCiAgICAgICAgICAgICBhZXMoeW1pbiA9IC5sb3dlciwgeW1heCA9IC51cHBlciwgZmlsbCA9IFRyZWF0bWVudCksIGFscGhhID0gMS8yKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFRyZWF0bWVudCwgY29sb3VyID0gVHJlYXRtZW50KSwgZGF0YSA9IHByZWRzX3N1bW1hcnksCiAgICAgICAgICAgIHNpemUgPSAxLCBhbHBoYSA9IDEsIGxpbmV0eXBlID0gNSkgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXMgPSBjKDEsIDIsIDMpKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSwgZ3VpZGUgPSAibm9uZSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSkgKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wMSwgMCkpKSArCiAgdGhlbWVfdGlkeWJheWVzKCkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygxLCAyMCksIHlsaW0gPSBjKDAsIDE1MCkpICsKICBsYWJzKHkgPSAiU3VicG9wdWxhdGlvbiBwcm9kdWN0aXZpdHkiLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIsIGZpbGwgPSAiSW5oZXJpdGFuY2UgdHJlYXRtZW50IikgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoLjk5LCAuOTkpLAogICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygicmlnaHQiLCAidG9wIiksCiAgICAgICAgbGVnZW5kLmJveC5qdXN0ID0gInJpZ2h0IiwKICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKDYsIDYsIDYsIDYpKQoKYGBgCgokfiQKCkVzdGltYXRpbmcgR2VuZXJhdGlvbiBvbmUgcHJvZHVjdGl2aXR5IGFuZCAkXGxhbWJkYSQgCgpPdXIgbW9kZWwgZXN0aW1hdGVzICRhJCB0aGUgaW5pdGlhbCBwcm9kdWN0aXZpdHkgcGFyYW1ldGVyLiBUaGlzIGlzIHRoZSBwcm9kdWN0aXZpdHkgaW4gZ2VuZXJhdGlvbiAwLCB3aGljaCBpbiBwcmFjdGljZSBpcyBub24tc2Vuc2ljYWwuIFdlIGluc3RlYWQgcHJlc2VudCBwcm9kdWN0aXZpdHkgaW4gZ2VuZXJhdGlvbiBvbmUgd2hpY2ggPSAkYSAtIGVee1xsYW1iZGEqMX0kLgoKYGBge3J9CgpHZW5fMV9wcm9kdWN0aXZpdHkgPC0KcHJlZHMgJT4lIAogIGZpbHRlcihHZW5lcmF0aW9uID09IDEpCiAgCgpJbml0aWFsX3Byb2R1Y3Rpdml0eV9wbG90IDwtCiAgR2VuXzFfcHJvZHVjdGl2aXR5ICU+JSAKICAKICBnZ3Bsb3QoYWVzKHggPSBDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcsIHkgPSBUcmVhdG1lbnQpKSArCiAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gVHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGxhYnMoeD0gIlByb2R1Y3Rpdml0eSBpbiBnZW5lcmF0aW9uIDEiLCB5ID0gIkluaGVyaXRhbmNlIHRyZWF0bWVudCIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcpLCAjdHJhbnNwYXJlbnQgcGFuZWwgYmcKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvcj1OQSksICN0cmFuc3BhcmVudCBwbG90IGJnCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgoKCmRlY2F5X2VzdGltYXRlcyA8LSAgCiAgYXNfZHJhd3NfZGYobm9ubGluZWFyX3Byb2R1Y3Rpdml0eSwgdmFyaWFibGUgPSAiXmJfbGFtYmRhIiwgcmVnZXggPSBUUlVFKSAlPiUgCiAgbXV0YXRlKGBGZW1hbGUtbGltaXRlZGAgPSBiX2xhbWJkYV9JbnRlcmNlcHQgKyBiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUsCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gYl9sYW1iZGFfSW50ZXJjZXB0ICsgYl9sYW1iZGFfVHJlYXRtZW50TWFsZSwKICAgICAgICAgQ29udHJvbCA9IGJfbGFtYmRhX0ludGVyY2VwdCkgJT4lCiBzZWxlY3QoYEZlbWFsZS1saW1pdGVkYCwgYE1hbGUtbGltaXRlZGAsIENvbnRyb2wpICU+JSAKICBtdXRhdGUocG9zdGVyaW9yX3NhbXBsZSA9IDE6bigpKSAlPiUgCiAgZ2F0aGVyKEV2b2x1dGlvbl90cmVhdG1lbnQsIGxhbWJkYSwgLXBvc3Rlcmlvcl9zYW1wbGUpCiAgCgpkZWNheV9wbG90IDwtCiAgZGVjYXlfZXN0aW1hdGVzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBsYW1iZGEsIHkgPSBFdm9sdXRpb25fdHJlYXRtZW50KSkgKwogICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gRXZvbHV0aW9uX3RyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMSwKICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLCAKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwgc2NhbGUgPSAwLjgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGxhYnMoeD1leHByZXNzaW9uKHBhc3RlKCJEZWNheSByYXRlIHBhcmFtZXRlciAiLCBsYW1iZGEsKSksIHkgPSBOVUxMKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKYGBgCgpDcmVhdGUgcGxvdHMgZCBhbmQgZQoKYGBge3J9CgpEaWZmZXJlbmNlX2dlbnNfcHJvZHVjdGl2aXR5IDwtIAogIHByZWRzICU+JSAKICBwaXZvdF93aWRlcih2YWx1ZXNfZnJvbSA9ICJDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmciLCBuYW1lc19mcm9tID0gIlRyZWF0bWVudCIpICU+JSAKICBtdXRhdGUoZGlmZi5tYyA9IGBNYWxlLWxpbWl0ZWRgIC0gQ29udHJvbCwKICAgICAgICAgZGlmZi5tZiA9IGBNYWxlLWxpbWl0ZWRgIC0gYEZlbWFsZS1saW1pdGVkYCwKICAgICAgICAgZGlmZi5mYyA9IGBGZW1hbGUtbGltaXRlZGAgLSBDb250cm9sKSAlPiUgCiAgc2VsZWN0KEdlbmVyYXRpb24sIGNvbnRhaW5zKCJkaWZmIikpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGNvbnRhaW5zKCJkaWZmIiksIHZhbHVlc190byA9ICJwcm9kdWN0aXZpdHlfZGlmZiIsIG5hbWVzX3RvID0gIkRpZmZlcmVuY2UgY29udHJhc3QiKSAKCiMgTWFrZSB0aGUgdGhyZWUgcGxvdHMKCkxlYWZfcGxvdF9tY19wcm9kdWN0aXZpdHkgPC0KICBEaWZmZXJlbmNlX2dlbnNfcHJvZHVjdGl2aXR5ICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYubWMiKSAlPiUgCiAgZ2dwbG90KGFlcyhwcm9kdWN0aXZpdHlfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlB1cnAiKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC01LCAyNSkpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIk1hbGUgLSBDb250cm9sXG5Qcm9kdWN0aXZpdHkgZGlmZi4iLAogICAgICAgeSA9ICJHZW5lcmF0aW9uIG9mIGluYnJlZWRpbmciKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKCkxlYWZfcGxvdF9tZl9wcm9kdWN0aXZpdHkgPC0KICBEaWZmZXJlbmNlX2dlbnNfcHJvZHVjdGl2aXR5ICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYubWYiKSAlPiUgCiAgZ2dwbG90KGFlcyhwcm9kdWN0aXZpdHlfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlRlYWxHcm4iKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC01LCAyNSkpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIk1hbGUgLSBGZW1hbGVcblByb2R1Y3Rpdml0eSBkaWZmLiIsCiAgICAgICB5ID0gTlVMTCkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkKCgpMZWFmX3Bsb3RfZmNfcHJvZHVjdGl2aXR5IDwtCiAgRGlmZmVyZW5jZV9nZW5zX3Byb2R1Y3Rpdml0eSAlPiUKICBmaWx0ZXIoYERpZmZlcmVuY2UgY29udHJhc3RgID09ICJkaWZmLmZjIikgJT4lIAogIGdncGxvdChhZXMocHJvZHVjdGl2aXR5X2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJQZWFjaCIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTUsIDI1KSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPXJldikgKwogIGdlb21fdmxpbmUobGluZXR5cGUgPSAyLCB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDEpICsKICBsYWJzKHggPSAiRmVtYWxlIC0gQ29udHJvbFxuUHJvZHVjdGl2aXR5IGRpZmYuIiwKICAgICAgIHkgPSBOVUxMKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKYGBgCgpDb21iaW5lIHRoZSA2IHBhbmVscwoKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMH0KKG5sX3AxIC8gKEluaXRpYWxfcHJvZHVjdGl2aXR5X3Bsb3QgKyBkZWNheV9wbG90KSkgLyAoTGVhZl9wbG90X21jX3Byb2R1Y3Rpdml0eSArIExlYWZfcGxvdF9tZl9wcm9kdWN0aXZpdHkgKyBMZWFmX3Bsb3RfZmNfcHJvZHVjdGl2aXR5KSArCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAnYScpICsgCiAgcGxvdF9sYXlvdXQoaGVpZ2h0cyA9IGMoMS41LCAxLCAxKSkKYGBgCgoqKkZpZ3VyZSAyKiouIFBhbmVsICoqYSoqIHNob3dzIHByb2R1Y3Rpdml0eSBkZWNsaW5lIHVuZGVyIGluY3JlYXNpbmcgc3RyZXNzIGZyb20gaW5icmVlZGluZywgc3BsaXQgYnkgaW5oZXJpdGFuY2UgdHJlYXRtZW50LiBCYW5kcyBhcmUgNTAlIGNyZWRpYmxlIGludGVydmFscyB0byBhaWQgdmlzdWFsIGluc3BlY3Rpb24gYW5kIGNpcmN1bGFyIHBvaW50cyBzaG93IHJhdyBwcm9kdWN0aXZpdHkgY291bnRzIGZvciBlYWNoIHN1Yi1wb3B1bGF0aW9uIGluIGVhY2ggZ2VuZXJhdGlvbi4gKipiKiogc2hvd3MgdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gb2YgcHJvZHVjdGl2aXR5IGluIHRoZSBmaXJzdCBnZW5lcmF0aW9uIG9mIHRoZSBleHBlcmltZW50OyB3aGl0ZSBwb2ludHMgYXJlIHRoZSBtZWRpYW4gd2l0aCBhc3NvY2lhdGVkIDY2IGFuZCA5NSUgY3JlZGlibGUgaW50ZXJ2YWxzLiAqKmMqKiBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBwcm9kdWN0aXZpdHkgZGVjYXkgcmF0ZSBmb3IgZWFjaCB0cmVhdG1lbnQuICoqZC1mKiogc2hvdyB0aGUgZGlmZmVyZW5jZSBjb250cmFzdHMgZm9yIHByb2R1Y3Rpdml0eSBpbiBlYWNoIGdlbmVyYXRpb24uIFRoZSBpbm5lcm1vc3QgY29sb3VyIGJhbmQgYXBwcm94aW1hdGVzIHRoZSBtZWRpYW4sIHdoaWxlIHRoZSBtaWRkbGUgYW5kIG91dGVybW9zdCBiYXJzIHNob3cgNjYgYW5kIDk1JSBjcmVkaWJsZSBpbnRlcnZhbHMuICA=